diff --git a/pkgs/jnigen/java/src/main/java/com/github/dart_lang/jnigen/apisummarizer/disasm/AsmClassVisitor.java b/pkgs/jnigen/java/src/main/java/com/github/dart_lang/jnigen/apisummarizer/disasm/AsmClassVisitor.java index 884d04ba24..723e52b529 100644 --- a/pkgs/jnigen/java/src/main/java/com/github/dart_lang/jnigen/apisummarizer/disasm/AsmClassVisitor.java +++ b/pkgs/jnigen/java/src/main/java/com/github/dart_lang/jnigen/apisummarizer/disasm/AsmClassVisitor.java @@ -87,6 +87,7 @@ public FieldVisitor visitField( var field = new Field(); field.name = name; field.type = TypeUtils.typeUsage(Type.getType(descriptor)); + field.descriptor = descriptor; field.defaultValue = value; field.modifiers = TypeUtils.access(access); if ((access & ACC_ENUM) != 0) { diff --git a/pkgs/jnigen/java/src/main/java/com/github/dart_lang/jnigen/apisummarizer/elements/Field.java b/pkgs/jnigen/java/src/main/java/com/github/dart_lang/jnigen/apisummarizer/elements/Field.java index ced5ceafeb..0afd9b0cd7 100644 --- a/pkgs/jnigen/java/src/main/java/com/github/dart_lang/jnigen/apisummarizer/elements/Field.java +++ b/pkgs/jnigen/java/src/main/java/com/github/dart_lang/jnigen/apisummarizer/elements/Field.java @@ -14,6 +14,7 @@ public class Field { public String name; public TypeUsage type; public Object defaultValue; + public String descriptor; public JavaDocComment javadoc; public List annotations = new ArrayList<>(); diff --git a/pkgs/jnigen/jnigen_symbols.json b/pkgs/jnigen/jnigen_symbols.json new file mode 100644 index 0000000000..00a1f6c39f --- /dev/null +++ b/pkgs/jnigen/jnigen_symbols.json @@ -0,0 +1,8753 @@ +{ + "formatVersion": "1.0.0", + "packageName": "tbd", + "files": { + "test/simple_package_test/bindings/simple_package.dart": { + "classes": { + "com.github.dart_lang.jnigen.simple_package.Example$Nested$NestedTwice": { + "name": "Example$Nested$NestedTwice", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "ZERO": { + "name": "ZERO", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + }, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "()V": { + "name": "$_clinit_", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.simple_package.Example$Nested": { + "name": "Example$Nested", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "value": { + "name": "value", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + }, + "methods": { + "(Z)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "usesAnonymousInnerClass()V": { + "name": "usesAnonymousInnerClass", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "getValue()Z": { + "name": "getValue", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + }, + "setValue(Z)V": { + "name": "setValue", + "typeParameters": [], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.simple_package.Example$NonStaticNested": { + "name": "Example$NonStaticNested", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "ok": { + "name": "ok", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + }, + "methods": { + "(Lcom/github/dart_lang/jnigen/simple_package/Example;)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "$$outerClass", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.simple_package.Example", + "typeArguments": [], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.simple_package.Example": { + "name": "Example", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "ON": { + "name": "ON", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "OFF": { + "name": "OFF", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "PI": { + "name": "PI", + "type": { + "kind": "primitive", + "type": { + "name": "double" + } + } + }, + "SEMICOLON": { + "name": "SEMICOLON", + "type": { + "kind": "primitive", + "type": { + "name": "char" + } + } + }, + "SEMICOLON_STRING": { + "name": "SEMICOLON_STRING", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "unusedRandom": { + "name": "unusedRandom", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Random", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "amount": { + "name": "amount", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "pi": { + "name": "pi", + "type": { + "kind": "primitive", + "type": { + "name": "double" + } + } + }, + "asterisk": { + "name": "asterisk", + "type": { + "kind": "primitive", + "type": { + "name": "char" + } + } + }, + "name": { + "name": "name", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "nested": { + "name": "nested", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.simple_package.Example$Nested", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "number": { + "name": "number", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "isUp": { + "name": "isUp", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + }, + "codename": { + "name": "codename", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "random": { + "name": "random", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Random", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "protectedField": { + "name": "protectedField", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Random", + "typeArguments": [], + "nullability": "platform" + } + } + } + }, + "methods": { + "getAmount()I": { + "name": "getAmount", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "getPi()D": { + "name": "getPi", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "double" + } + } + }, + "getAsterisk()C": { + "name": "getAsterisk", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "char" + } + } + }, + "getName()Ljava/lang/String;": { + "name": "getName", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "getNestedInstance()Lcom/github/dart_lang/jnigen/simple_package/Example$Nested;": { + "name": "getNestedInstance", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.simple_package.Example$Nested", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "setAmount(I)V": { + "name": "setAmount", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "setName(Ljava/lang/String;)V": { + "name": "setName", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "setNestedInstance(Lcom/github/dart_lang/jnigen/simple_package/Example$Nested;)V": { + "name": "setNestedInstance", + "typeParameters": [], + "methodParameters": [ + { + "name": "nested", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.simple_package.Example$Nested", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "max4(IIII)I": { + "name": "max4", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i1", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i2", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i3", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "max8(IIIIIIII)I": { + "name": "max8", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i1", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i2", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i3", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i4", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i5", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i6", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i7", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "getNumber()I": { + "name": "getNumber", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "setNumber(I)V": { + "name": "setNumber", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "getIsUp()Z": { + "name": "getIsUp", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + }, + "setUp(Z)V": { + "name": "setUp", + "typeParameters": [], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "getCodename()Ljava/lang/String;": { + "name": "getCodename", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "setCodename(Ljava/lang/String;)V": { + "name": "setCodename", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "getRandom()Ljava/util/Random;": { + "name": "getRandom", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.Random", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "setRandom(Ljava/util/Random;)V": { + "name": "setRandom", + "typeParameters": [], + "methodParameters": [ + { + "name": "random", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Random", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "getRandomLong()J": { + "name": "getRandomLong", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + "add4Longs(JJJJ)J": { + "name": "add4Longs", + "typeParameters": [], + "methodParameters": [ + { + "name": "j", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + { + "name": "j1", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + { + "name": "j2", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + { + "name": "j3", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + "add8Longs(JJJJJJJJ)J": { + "name": "add8Longs", + "typeParameters": [], + "methodParameters": [ + { + "name": "j", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + { + "name": "j1", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + { + "name": "j2", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + { + "name": "j3", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + { + "name": "j4", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + { + "name": "j5", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + { + "name": "j6", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + { + "name": "j7", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + "getRandomNumericString(Ljava/util/Random;)Ljava/lang/String;": { + "name": "getRandomNumericString", + "typeParameters": [], + "methodParameters": [ + { + "name": "random", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Random", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "privateMethod(Ljava/lang/String;Ljava/lang/String;)V": { + "name": "privateMethod", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + { + "name": "string1", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "protectedMethod(Ljava/lang/String;Ljava/lang/String;)V": { + "name": "protectedMethod", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + { + "name": "string1", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "finalMethod()V": { + "name": "finalMethod", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "getList()Ljava/util/List;": { + "name": "getList", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "joinStrings(Ljava/util/List;Ljava/lang/String;)Ljava/lang/String;": { + "name": "joinStrings", + "typeParameters": [], + "methodParameters": [ + { + "name": "list", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "methodWithSeveralParams(CLjava/lang/String;[ILjava/lang/CharSequence;Ljava/util/List;Ljava/util/Map;)V": { + "name": "methodWithSeveralParams", + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.CharSequence", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "c", + "type": { + "kind": "primitive", + "type": { + "name": "char" + } + } + }, + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + { + "name": "is$", + "type": { + "kind": "declared", + "type": { + "elementType": { + "kind": "primitive", + "type": { + "name": "int" + } + }, + "nullability": "platform" + } + } + }, + { + "name": "charSequence", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + { + "name": "list", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + { + "name": "map", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + }, + { + "kind": "wildcard", + "type": { + "extendsBound": { + "kind": "declared", + "type": { + "binaryName": "java.lang.CharSequence", + "typeArguments": [], + "nullability": "platform" + } + }, + "superBound": null, + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "(I)V": { + "name": "new$1", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "(IZ)V": { + "name": "new$2", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "(IZLjava/lang/String;)V": { + "name": "new$3", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + }, + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "(IIIIIIII)V": { + "name": "new$4", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i1", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i2", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i3", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i4", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i5", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i6", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i7", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "whichExample()I": { + "name": "whichExample", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "addInts(II)I": { + "name": "addInts", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i1", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "getArr()[I": { + "name": "getArr", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "primitive", + "type": { + "name": "int" + } + }, + "nullability": "platform" + } + } + }, + "addAll([I)I": { + "name": "addAll", + "typeParameters": [], + "methodParameters": [ + { + "name": "is$", + "type": { + "kind": "declared", + "type": { + "elementType": { + "kind": "primitive", + "type": { + "name": "int" + } + }, + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "getSelf()Lcom/github/dart_lang/jnigen/simple_package/Example;": { + "name": "getSelf", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.simple_package.Example", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "throwException()V": { + "name": "throwException", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "overloaded()V": { + "name": "overloaded", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "overloaded(ILjava/lang/String;)V": { + "name": "overloaded$1", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "overloaded(I)V": { + "name": "overloaded$2", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "overloaded(Ljava/util/List;Ljava/lang/String;)V": { + "name": "overloaded$3", + "typeParameters": [], + "methodParameters": [ + { + "name": "list", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Integer", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "overloaded(Ljava/util/List;)V": { + "name": "overloaded$4", + "typeParameters": [], + "methodParameters": [ + { + "name": "list", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Integer", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "()V": { + "name": "$_clinit_", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.simple_package.Exceptions": { + "name": "Exceptions", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "(F)V": { + "name": "new$1", + "typeParameters": [], + "methodParameters": [ + { + "name": "f", + "type": { + "kind": "primitive", + "type": { + "name": "float" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "(IIIIII)V": { + "name": "new$2", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i1", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i2", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i3", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i4", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i5", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "staticObjectMethod()Ljava/lang/Object;": { + "name": "staticObjectMethod", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "staticIntMethod()I": { + "name": "staticIntMethod", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "staticObjectArrayMethod()[Ljava/lang/Object;": { + "name": "staticObjectArrayMethod", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "nullability": "platform" + } + } + }, + "staticIntArrayMethod()[I": { + "name": "staticIntArrayMethod", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "primitive", + "type": { + "name": "int" + } + }, + "nullability": "platform" + } + } + }, + "objectMethod()Ljava/lang/Object;": { + "name": "objectMethod", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "intMethod()I": { + "name": "intMethod", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "objectArrayMethod()[Ljava/lang/Object;": { + "name": "objectArrayMethod", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "nullability": "platform" + } + } + }, + "intArrayMethod()[I": { + "name": "intArrayMethod", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "primitive", + "type": { + "name": "int" + } + }, + "nullability": "platform" + } + } + }, + "throwNullPointerException()I": { + "name": "throwNullPointerException", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "throwFileNotFoundException()Ljava/io/InputStream;": { + "name": "throwFileNotFoundException", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.io.InputStream", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "throwClassCastException()Ljava/io/FileInputStream;": { + "name": "throwClassCastException", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.io.FileInputStream", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "throwArrayIndexException()I": { + "name": "throwArrayIndexException", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "throwArithmeticException()I": { + "name": "throwArithmeticException", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "throwLoremIpsum()V": { + "name": "throwLoremIpsum", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.simple_package.Fields$Nested": { + "name": "Fields$Nested", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "hundred": { + "name": "hundred", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + "BEST_GOD": { + "name": "BEST_GOD", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + }, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "()V": { + "name": "$_clinit_", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.simple_package.Fields": { + "name": "Fields", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "amount": { + "name": "amount", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "pi": { + "name": "pi", + "type": { + "kind": "primitive", + "type": { + "name": "double" + } + } + }, + "asterisk": { + "name": "asterisk", + "type": { + "kind": "primitive", + "type": { + "name": "char" + } + } + }, + "name": { + "name": "name", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "i": { + "name": "i", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Integer", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "trillion": { + "name": "trillion", + "type": { + "kind": "primitive", + "type": { + "name": "long" + } + } + }, + "isAchillesDead": { + "name": "isAchillesDead", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + }, + "bestFighterInGreece": { + "name": "bestFighterInGreece", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "random": { + "name": "random", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Random", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "euroSymbol": { + "name": "euroSymbol", + "type": { + "kind": "primitive", + "type": { + "name": "char" + } + } + } + }, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "()V": { + "name": "$_clinit_", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.pkg2.C2": { + "name": "C2", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "CONSTANT": { + "name": "CONSTANT", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + }, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "()V": { + "name": "$_clinit_", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.pkg2.Example": { + "name": "Example$1", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "whichExample()I": { + "name": "whichExample", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.enums.Colors$RGB": { + "name": "Colors$RGB", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "red": { + "name": "red", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "green": { + "name": "green", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + "blue": { + "name": "blue", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + }, + "methods": { + "(III)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i1", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i2", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "equals(Ljava/lang/Object;)Z": { + "name": "equals", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + }, + "hashCode()I": { + "name": "hashCode", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.enums.Colors": { + "name": "Colors", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Enum", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.enums.Colors", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "red": { + "name": "red", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.enums.Colors", + "typeArguments": [], + "nullability": "nonNullable" + } + } + }, + "green": { + "name": "green", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.enums.Colors", + "typeArguments": [], + "nullability": "nonNullable" + } + } + }, + "blue": { + "name": "blue", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.enums.Colors", + "typeArguments": [], + "nullability": "nonNullable" + } + } + }, + "code": { + "name": "code", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + }, + "methods": { + "values()[Lcom/github/dart_lang/jnigen/enums/Colors;": { + "name": "values", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.enums.Colors", + "typeArguments": [], + "nullability": "platform" + } + }, + "nullability": "platform" + } + } + }, + "valueOf(Ljava/lang/String;)Lcom/github/dart_lang/jnigen/enums/Colors;": { + "name": "valueOf", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.enums.Colors", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "(Ljava/lang/String;II)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "i1", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "toRGB()Lcom/github/dart_lang/jnigen/enums/Colors$RGB;": { + "name": "toRGB", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.enums.Colors$RGB", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "()V": { + "name": "$_clinit_", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.generics.GenericTypeParams": { + "name": "GenericTypeParams", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [ + { + "name": "S", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.CharSequence", + "typeArguments": [], + "nullability": "platform" + } + } + ] + }, + { + "name": "K", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.GenericTypeParams", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "K", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.generics.GrandParent$Parent$Child": { + "name": "GrandParent$Parent$Child", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "grandParentValue": { + "name": "grandParentValue", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "parentValue": { + "name": "parentValue", + "type": { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + }, + "value": { + "name": "value", + "type": { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + } + }, + "methods": { + "(Lcom/github/dart_lang/jnigen/generics/GrandParent$Parent;Ljava/lang/Object;)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "$$outerClass", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.GrandParent$Parent", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + }, + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + }, + { + "name": "S", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + }, + { + "name": "U", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.generics.GrandParent$Parent": { + "name": "GrandParent$Parent", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "parentValue": { + "name": "parentValue", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "value": { + "name": "value", + "type": { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + } + }, + "methods": { + "(Lcom/github/dart_lang/jnigen/generics/GrandParent;Ljava/lang/Object;)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "$$outerClass", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.GrandParent", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + }, + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + }, + { + "name": "S", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.generics.GrandParent$StaticParent$Child": { + "name": "GrandParent$StaticParent$Child", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "parentValue": { + "name": "parentValue", + "type": { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + }, + "value": { + "name": "value", + "type": { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + } + }, + "methods": { + "(Lcom/github/dart_lang/jnigen/generics/GrandParent$StaticParent;Ljava/lang/Object;Ljava/lang/Object;)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "$$outerClass", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.GrandParent$StaticParent", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + }, + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + }, + { + "name": "object1", + "type": { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [ + { + "name": "S", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + }, + { + "name": "U", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.generics.GrandParent$StaticParent": { + "name": "GrandParent$StaticParent", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "value": { + "name": "value", + "type": { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + } + }, + "methods": { + "(Ljava/lang/Object;)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [ + { + "name": "S", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.generics.GrandParent": { + "name": "GrandParent", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "value": { + "name": "value", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + } + }, + "methods": { + "(Ljava/lang/Object;)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "stringParent()Lcom/github/dart_lang/jnigen/generics/GrandParent$Parent;": { + "name": "stringParent", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.GrandParent$Parent", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "varParent(Ljava/lang/Object;)Lcom/github/dart_lang/jnigen/generics/GrandParent$Parent;": { + "name": "varParent", + "typeParameters": [ + { + "name": "S", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.GrandParent$Parent", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "stringStaticParent()Lcom/github/dart_lang/jnigen/generics/GrandParent$StaticParent;": { + "name": "stringStaticParent", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.GrandParent$StaticParent", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "varStaticParent(Ljava/lang/Object;)Lcom/github/dart_lang/jnigen/generics/GrandParent$StaticParent;": { + "name": "varStaticParent", + "typeParameters": [ + { + "name": "S", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.GrandParent$StaticParent", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "staticParentWithSameType()Lcom/github/dart_lang/jnigen/generics/GrandParent$StaticParent;": { + "name": "staticParentWithSameType", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.GrandParent$StaticParent", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + }, + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.generics.MyMap$MyEntry": { + "name": "MyMap$MyEntry", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "key": { + "name": "key", + "type": { + "kind": "typeVariable", + "type": { + "name": "K", + "nullability": "platform" + } + } + }, + "value": { + "name": "value", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + } + }, + "methods": { + "(Lcom/github/dart_lang/jnigen/generics/MyMap;Ljava/lang/Object;Ljava/lang/Object;)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "$$outerClass", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyMap", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "K", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + }, + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "K", + "nullability": "platform" + } + } + }, + { + "name": "object1", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [ + { + "name": "K", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + }, + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.generics.MyMap": { + "name": "MyMap", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "map": { + "name": "map", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "K", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + }, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "get(Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "get", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "K", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "put", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "K", + "nullability": "platform" + } + } + }, + { + "name": "object1", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "entryStack()Lcom/github/dart_lang/jnigen/generics/MyStack;": { + "name": "entryStack", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyStack", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyMap$MyEntry", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "K", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + }, + "typeParameters": [ + { + "name": "K", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + }, + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.generics.MyStack": { + "name": "MyStack", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "stack": { + "name": "stack", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Stack", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + }, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "fromArray([Ljava/lang/Object;)Lcom/github/dart_lang/jnigen/generics/MyStack;": { + "name": "fromArray", + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "objects", + "type": { + "kind": "declared", + "type": { + "elementType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyStack", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "fromArrayOfArrayOfGrandParents([[Lcom/github/dart_lang/jnigen/generics/GrandParent;)Lcom/github/dart_lang/jnigen/generics/MyStack;": { + "name": "fromArrayOfArrayOfGrandParents", + "typeParameters": [ + { + "name": "S", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "grandParents", + "type": { + "kind": "declared", + "type": { + "elementType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.GrandParent", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + }, + "nullability": "platform" + } + }, + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyStack", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "S", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "of()Lcom/github/dart_lang/jnigen/generics/MyStack;": { + "name": "of", + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyStack", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "of(Ljava/lang/Object;)Lcom/github/dart_lang/jnigen/generics/MyStack;": { + "name": "of$1", + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyStack", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "of(Ljava/lang/Object;Ljava/lang/Object;)Lcom/github/dart_lang/jnigen/generics/MyStack;": { + "name": "of$2", + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + { + "name": "object1", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyStack", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "push(Ljava/lang/Object;)V": { + "name": "push", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "pop()Ljava/lang/Object;": { + "name": "pop", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "size()I": { + "name": "size", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + }, + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.generics.StringKeyedMap": { + "name": "StringKeyedMap", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyMap", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "get(Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "get", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "put", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + { + "name": "object1", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "entryStack()Lcom/github/dart_lang/jnigen/generics/MyStack;": { + "name": "entryStack", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyStack", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyMap$MyEntry", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + }, + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.generics.StringMap": { + "name": "StringMap", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.StringKeyedMap", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "get(Ljava/lang/String;)Ljava/lang/Object;": { + "name": "get", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "put(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "put", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + { + "name": "object1", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "entryStack()Lcom/github/dart_lang/jnigen/generics/MyStack;": { + "name": "entryStack", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyStack", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyMap$MyEntry", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + }, + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.generics.StringStack": { + "name": "StringStack", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyStack", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "push(Ljava/lang/Object;)V": { + "name": "push", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "pop()Ljava/lang/Object;": { + "name": "pop", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "size()I": { + "name": "size", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.generics.StringValuedMap": { + "name": "StringValuedMap", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyMap", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "K", + "nullability": "platform" + } + }, + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "get(Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "get", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "K", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "put", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "K", + "nullability": "platform" + } + } + }, + { + "name": "object1", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "entryStack()Lcom/github/dart_lang/jnigen/generics/MyStack;": { + "name": "entryStack", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyStack", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.generics.MyMap$MyEntry", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "K", + "nullability": "platform" + } + }, + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + }, + "typeParameters": [ + { + "name": "K", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.interfaces.GenericInterface": { + "name": "GenericInterface", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "genericArrayOf(Ljava/lang/Object;)[Ljava/lang/Object;": { + "name": "genericArrayOf", + "typeParameters": [ + { + "name": "U", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + }, + "nullability": "platform" + } + } + }, + "arrayOf(Ljava/lang/Object;)[Ljava/lang/Object;": { + "name": "arrayOf", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + "nullability": "platform" + } + } + }, + "mapOf(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/Map;": { + "name": "mapOf", + "typeParameters": [ + { + "name": "U", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + { + "name": "object1", + "type": { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "firstOfGenericArray([Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "firstOfGenericArray", + "typeParameters": [ + { + "name": "U", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "objects", + "type": { + "kind": "declared", + "type": { + "elementType": { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + }, + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + }, + "firstOfArray([Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "firstOfArray", + "typeParameters": [], + "methodParameters": [ + { + "name": "objects", + "type": { + "kind": "declared", + "type": { + "elementType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "firstKeyOf(Ljava/util/Map;)Ljava/lang/Object;": { + "name": "firstKeyOf", + "typeParameters": [ + { + "name": "U", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "map", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "firstValueOf(Ljava/util/Map;)Ljava/lang/Object;": { + "name": "firstValueOf", + "typeParameters": [ + { + "name": "U", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "map", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + } + }, + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.interfaces.InheritedFromMyInterface": { + "name": "InheritedFromMyInterface", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [ + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.interfaces.MyInterface", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + ], + "fields": {}, + "methods": { + "voidCallback(Ljava/lang/String;)V": { + "name": "voidCallback", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "stringCallback(Ljava/lang/String;)Ljava/lang/String;": { + "name": "stringCallback", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "varCallback(Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "varCallback", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "manyPrimitives(IZCD)J": { + "name": "manyPrimitives", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + }, + { + "name": "c", + "type": { + "kind": "primitive", + "type": { + "name": "char" + } + } + }, + { + "name": "d", + "type": { + "kind": "primitive", + "type": { + "name": "double" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "long" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.interfaces.InheritedFromMyRunnable": { + "name": "InheritedFromMyRunnable", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [ + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.interfaces.MyRunnable", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "fields": {}, + "methods": { + "run()V": { + "name": "run", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.interfaces.MyInterface": { + "name": "MyInterface", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "voidCallback(Ljava/lang/String;)V": { + "name": "voidCallback", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "stringCallback(Ljava/lang/String;)Ljava/lang/String;": { + "name": "stringCallback", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "varCallback(Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "varCallback", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "manyPrimitives(IZCD)J": { + "name": "manyPrimitives", + "typeParameters": [], + "methodParameters": [ + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + }, + { + "name": "c", + "type": { + "kind": "primitive", + "type": { + "name": "char" + } + } + }, + { + "name": "d", + "type": { + "kind": "primitive", + "type": { + "name": "double" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "long" + } + } + } + }, + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.interfaces.MyInterfaceConsumer": { + "name": "MyInterfaceConsumer", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "consumeOnAnotherThread(Lcom/github/dart_lang/jnigen/interfaces/MyInterface;Ljava/lang/String;IZCDLjava/lang/Object;)V": { + "name": "consumeOnAnotherThread", + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "myInterface", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.interfaces.MyInterface", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + }, + { + "name": "c", + "type": { + "kind": "primitive", + "type": { + "name": "char" + } + } + }, + { + "name": "d", + "type": { + "kind": "primitive", + "type": { + "name": "double" + } + } + }, + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "consumeOnSameThread(Lcom/github/dart_lang/jnigen/interfaces/MyInterface;Ljava/lang/String;IZCDLjava/lang/Object;)V": { + "name": "consumeOnSameThread", + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "myInterface", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.interfaces.MyInterface", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + }, + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + }, + { + "name": "c", + "type": { + "kind": "primitive", + "type": { + "name": "char" + } + } + }, + { + "name": "d", + "type": { + "kind": "primitive", + "type": { + "name": "double" + } + } + }, + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.interfaces.MyRunnable": { + "name": "MyRunnable", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "run()V": { + "name": "run", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.interfaces.MyRunnableRunner": { + "name": "MyRunnableRunner", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "runnable": { + "name": "runnable", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.interfaces.MyRunnable", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "error": { + "name": "error", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Throwable", + "typeArguments": [], + "nullability": "platform" + } + } + } + }, + "methods": { + "(Lcom/github/dart_lang/jnigen/interfaces/MyRunnable;)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "myRunnable", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.interfaces.MyRunnable", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "runOnSameThread()V": { + "name": "runOnSameThread", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "runOnAnotherThread()V": { + "name": "runOnAnotherThread", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "runOnAnotherThreadAndJoin()V": { + "name": "runOnAnotherThreadAndJoin", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.interfaces.StringConversionException": { + "name": "StringConversionException", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Exception", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "(Ljava/lang/String;)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.interfaces.StringConverter": { + "name": "StringConverter", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "parseToInt(Ljava/lang/String;)I": { + "name": "parseToInt", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.interfaces.StringConverterConsumer": { + "name": "StringConverterConsumer", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "consumeOnSameThread(Lcom/github/dart_lang/jnigen/interfaces/StringConverter;Ljava/lang/String;)Ljava/lang/Integer;": { + "name": "consumeOnSameThread", + "typeParameters": [], + "methodParameters": [ + { + "name": "stringConverter", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.interfaces.StringConverter", + "typeArguments": [], + "nullability": "platform" + } + } + }, + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Integer", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "consumeOnAnotherThread(Lcom/github/dart_lang/jnigen/interfaces/StringConverter;Ljava/lang/String;)Ljava/util/concurrent/Future;": { + "name": "consumeOnAnotherThread", + "typeParameters": [], + "methodParameters": [ + { + "name": "stringConverter", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.interfaces.StringConverter", + "typeArguments": [], + "nullability": "platform" + } + } + }, + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.concurrent.Future", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Integer", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.inheritance.BaseClass": { + "name": "BaseClass", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.CharSequence", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.inheritance.BaseGenericInterface": { + "name": "BaseGenericInterface", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "foo()Ljava/lang/Object;": { + "name": "foo", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + } + }, + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.inheritance.BaseInterface": { + "name": "BaseInterface", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "foo()Ljava/lang/String;": { + "name": "foo", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.inheritance.DerivedInterface": { + "name": "DerivedInterface", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [ + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.inheritance.BaseGenericInterface", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + }, + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.inheritance.BaseInterface", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "fields": {}, + "methods": { + "foo()Ljava/lang/String;": { + "name": "foo", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "foo()Ljava/lang/Object;": { + "name": "foo", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.inheritance.GenericDerivedClass": { + "name": "GenericDerivedClass", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.inheritance.BaseClass", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.CharSequence", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.inheritance.SpecificDerivedClass": { + "name": "SpecificDerivedClass", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.inheritance.BaseClass", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.annotations.Annotated$Nested": { + "name": "Annotated$Nested", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "v": { + "name": "v", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "u": { + "name": "u", + "type": { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "nonNullable" + } + } + } + }, + "methods": { + "(Lcom/github/dart_lang/jnigen/annotations/Annotated;Ljava/lang/Object;)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "$$outerClass", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.annotations.Annotated", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "nonNullable" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "W", + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + }, + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + }, + { + "name": "U", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "nonNullable" + } + } + ] + }, + { + "name": "W", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + }, + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.annotations.Annotated": { + "name": "Annotated", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "t": { + "name": "t", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "u": { + "name": "u", + "type": { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + }, + "w": { + "name": "w", + "type": { + "kind": "typeVariable", + "type": { + "name": "W", + "nullability": "platform" + } + } + } + }, + "methods": { + "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + { + "name": "object1", + "type": { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + }, + { + "name": "object2", + "type": { + "kind": "typeVariable", + "type": { + "name": "W", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "staticHello()Ljava/lang/String;": { + "name": "staticHello", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "nonNullable" + } + } + }, + "hello()Ljava/lang/String;": { + "name": "hello", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "nonNullable" + } + } + }, + "nullableHello(Z)Ljava/lang/String;": { + "name": "nullableHello", + "typeParameters": [], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "echo(Ljava/lang/String;)Ljava/lang/String;": { + "name": "echo", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "nonNullable" + } + } + }, + "nullableEcho(Ljava/lang/String;)Ljava/lang/String;": { + "name": "nullableEcho", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "array()[Ljava/lang/String;": { + "name": "array", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "nonNullable" + } + }, + "nullability": "nonNullable" + } + } + }, + "arrayOfNullable()[Ljava/lang/String;": { + "name": "arrayOfNullable", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + }, + "nullability": "nonNullable" + } + } + }, + "nullableArray(Z)[Ljava/lang/String;": { + "name": "nullableArray", + "typeParameters": [], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "nonNullable" + } + }, + "nullability": "platform" + } + } + }, + "nullableArrayOfNullable(Z)[Ljava/lang/String;": { + "name": "nullableArrayOfNullable", + "typeParameters": [], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + }, + "nullability": "platform" + } + } + }, + "list()Ljava/util/List;": { + "name": "list", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + }, + "listOfNullable()Ljava/util/List;": { + "name": "listOfNullable", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + }, + "nullableList(Z)Ljava/util/List;": { + "name": "nullableList", + "typeParameters": [], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "nonNullable" + } + } + ], + "nullability": "platform" + } + } + }, + "nullableListOfNullable(Z)Ljava/util/List;": { + "name": "nullableListOfNullable", + "typeParameters": [], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "classGenericEcho(Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "classGenericEcho", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "nonNullable" + } + } + }, + "nullableClassGenericEcho(Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "nullableClassGenericEcho", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "methodGenericEcho(Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "methodGenericEcho", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + }, + "methodGenericEcho2(Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "methodGenericEcho2", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "methodGenericEcho3(Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "methodGenericEcho3", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "nonNullable" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "nullableReturnMethodGenericEcho(Ljava/lang/Object;Z)Ljava/lang/Object;": { + "name": "nullableReturnMethodGenericEcho", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + }, + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "nullableReturnMethodGenericEcho2(Ljava/lang/Object;Z)Ljava/lang/Object;": { + "name": "nullableReturnMethodGenericEcho2", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nullable" + } + } + }, + "nullableMethodGenericEcho(Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "nullableMethodGenericEcho", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "noAnnotationMethodGenericEcho(Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "noAnnotationMethodGenericEcho", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "nullableArgMethodGenericEcho(Ljava/lang/Object;)Ljava/lang/Object;": { + "name": "nullableArgMethodGenericEcho", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "classGenericList()Ljava/util/List;": { + "name": "classGenericList", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + }, + "classGenericListOfNullable()Ljava/util/List;": { + "name": "classGenericListOfNullable", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + }, + "nullableClassGenericList(Z)Ljava/util/List;": { + "name": "nullableClassGenericList", + "typeParameters": [], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "nonNullable" + } + } + ], + "nullability": "platform" + } + } + }, + "nullableClassGenericListOfNullable(Z)Ljava/util/List;": { + "name": "nullableClassGenericListOfNullable", + "typeParameters": [], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "methodGenericList(Ljava/lang/Object;)Ljava/util/List;": { + "name": "methodGenericList", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + }, + "methodGenericListOfNullable()Ljava/util/List;": { + "name": "methodGenericListOfNullable", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + }, + "nullableMethodGenericList(Ljava/lang/Object;Z)Ljava/util/List;": { + "name": "nullableMethodGenericList", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + }, + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + ], + "nullability": "platform" + } + } + }, + "nullableMethodGenericListOfNullable(Z)Ljava/util/List;": { + "name": "nullableMethodGenericListOfNullable", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + }, + "firstOfClassGenericList(Ljava/util/List;)Ljava/lang/Object;": { + "name": "firstOfClassGenericList", + "typeParameters": [], + "methodParameters": [ + { + "name": "list", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "firstOfClassGenericNullableList(Ljava/util/List;)Ljava/lang/Object;": { + "name": "firstOfClassGenericNullableList", + "typeParameters": [], + "methodParameters": [ + { + "name": "list", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "nonNullable" + } + } + ], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "firstOfClassGenericListOfNullable(Ljava/util/List;)Ljava/lang/Object;": { + "name": "firstOfClassGenericListOfNullable", + "typeParameters": [], + "methodParameters": [ + { + "name": "list", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "firstOfClassGenericNullableListOfNullable(Ljava/util/List;)Ljava/lang/Object;": { + "name": "firstOfClassGenericNullableListOfNullable", + "typeParameters": [], + "methodParameters": [ + { + "name": "list", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "firstOfMethodGenericList(Ljava/util/List;)Ljava/lang/Object;": { + "name": "firstOfMethodGenericList", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "list", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "firstOfMethodGenericNullableList(Ljava/util/List;)Ljava/lang/Object;": { + "name": "firstOfMethodGenericNullableList", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "list", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + ], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "firstOfMethodGenericListOfNullable(Ljava/util/List;)Ljava/lang/Object;": { + "name": "firstOfMethodGenericListOfNullable", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "list", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "firstOfMethodGenericNullableListOfNullable(Ljava/util/List;)Ljava/lang/Object;": { + "name": "firstOfMethodGenericNullableListOfNullable", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "list", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "firstKeyOfComboMap(Ljava/util/Map;)Ljava/lang/Object;": { + "name": "firstKeyOfComboMap", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "map", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "nonNullable" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "firstValueOfComboMap(Ljava/util/Map;)Ljava/lang/Object;": { + "name": "firstValueOfComboMap", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "map", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "nonNullable" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "firstKeyOfComboMapNullableKey(Ljava/util/Map;)Ljava/lang/Object;": { + "name": "firstKeyOfComboMapNullableKey", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "map", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "firstValueOfComboMapNullableKey(Ljava/util/Map;)Ljava/lang/Object;": { + "name": "firstValueOfComboMapNullableKey", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "map", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "firstKeyOfComboMapNullableValue(Ljava/util/Map;)Ljava/lang/Object;": { + "name": "firstKeyOfComboMapNullableValue", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "map", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "nonNullable" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "firstValueOfComboMapNullableValue(Ljava/util/Map;)Ljava/lang/Object;": { + "name": "firstValueOfComboMapNullableValue", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "map", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "nonNullable" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "firstKeyOfComboMapNullableKeyAndValue(Ljava/util/Map;)Ljava/lang/Object;": { + "name": "firstKeyOfComboMapNullableKeyAndValue", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "map", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + }, + "firstValueOfComboMapNullableKeyAndValue(Ljava/util/Map;)Ljava/lang/Object;": { + "name": "firstValueOfComboMapNullableKeyAndValue", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "map", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "platform" + } + } + }, + "firstEntryOfComboMap(Ljava/util/Map;)Ljava/util/Map$Entry;": { + "name": "firstEntryOfComboMap", + "typeParameters": [ + { + "name": "V", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ], + "methodParameters": [ + { + "name": "map", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "nonNullable" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.Map$Entry", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "nonNullable" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "V", + "nullability": "nonNullable" + } + } + ], + "nullability": "platform" + } + } + }, + "getW()Ljava/lang/Object;": { + "name": "getW", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "W", + "nullability": "platform" + } + } + }, + "nullableGetW(Z)Ljava/lang/Object;": { + "name": "nullableGetW", + "typeParameters": [], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "W", + "nullability": "nullable" + } + } + }, + "list3dOfT()Ljava/util/List;": { + "name": "list3dOfT", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + }, + "list3dOfU()Ljava/util/List;": { + "name": "list3dOfU", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + }, + "list3dOfW()Ljava/util/List;": { + "name": "list3dOfW", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "W", + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + }, + "list3dOfNullableU(Z)Ljava/util/List;": { + "name": "list3dOfNullableU", + "typeParameters": [], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "nullable" + } + } + ], + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + }, + "list3dOfNullableW(Z)Ljava/util/List;": { + "name": "list3dOfNullableW", + "typeParameters": [], + "methodParameters": [ + { + "name": "z", + "type": { + "kind": "primitive", + "type": { + "name": "boolean" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "W", + "nullability": "nullable" + } + } + ], + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + ], + "nullability": "nonNullable" + } + } + }, + "nested()Lcom/github/dart_lang/jnigen/annotations/Annotated$Nested;": { + "name": "nested", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.annotations.Annotated$Nested", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "U", + "nullability": "platform" + } + }, + { + "kind": "typeVariable", + "type": { + "name": "W", + "nullability": "platform" + } + }, + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Integer", + "typeArguments": [], + "nullability": "nonNullable" + } + } + ], + "nullability": "platform" + } + } + }, + "intList()Ljava/util/List;": { + "name": "intList", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "java.util.List", + "typeArguments": [ + { + "kind": "wildcard", + "type": { + "extendsBound": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Integer", + "typeArguments": [], + "nullability": "nonNullable" + } + }, + "superBound": null, + "nullability": "platform" + } + } + ], + "nullability": "nonNullable" + } + } + } + }, + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + }, + { + "name": "U", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "nonNullable" + } + } + ] + }, + { + "name": "W", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.annotations.JsonSerializable$Case": { + "name": "JsonSerializable$Case", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Enum", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.annotations.JsonSerializable$Case", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": { + "SNAKE_CASE": { + "name": "SNAKE_CASE", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.annotations.JsonSerializable$Case", + "typeArguments": [], + "nullability": "nonNullable" + } + } + }, + "KEBAB_CASE": { + "name": "KEBAB_CASE", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.annotations.JsonSerializable$Case", + "typeArguments": [], + "nullability": "nonNullable" + } + } + }, + "CAMEL_CASE": { + "name": "CAMEL_CASE", + "type": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.annotations.JsonSerializable$Case", + "typeArguments": [], + "nullability": "nonNullable" + } + } + } + }, + "methods": { + "values()[Lcom/github/dart_lang/jnigen/annotations/JsonSerializable$Case;": { + "name": "values", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "elementType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.annotations.JsonSerializable$Case", + "typeArguments": [], + "nullability": "platform" + } + }, + "nullability": "platform" + } + } + }, + "valueOf(Ljava/lang/String;)Lcom/github/dart_lang/jnigen/annotations/JsonSerializable$Case;": { + "name": "valueOf", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.annotations.JsonSerializable$Case", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "(Ljava/lang/String;I)V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [ + { + "name": "string", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.String", + "typeArguments": [], + "nullability": "platform" + } + } + }, + { + "name": "i", + "type": { + "kind": "primitive", + "type": { + "name": "int" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "()V": { + "name": "$_clinit_", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.annotations.JsonSerializable": { + "name": "JsonSerializable", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.annotation.Annotation", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "fields": {}, + "methods": { + "value()Lcom/github/dart_lang/jnigen/annotations/JsonSerializable$Case;": { + "name": "value", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.annotations.JsonSerializable$Case", + "typeArguments": [], + "nullability": "platform" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.annotations.MyDataClass": { + "name": "MyDataClass", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.annotations.NotNull": { + "name": "NotNull", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.annotation.Annotation", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "fields": {}, + "methods": {}, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.annotations.Nullable": { + "name": "Nullable", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.annotation.Annotation", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "fields": {}, + "methods": {}, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.regressions.R2250$Child": { + "name": "R2250$Child", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [ + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.regressions.R2250", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "fields": {}, + "methods": { + "foo(Ljava/lang/Object;)V": { + "name": "foo", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.regressions.R2250": { + "name": "R2250", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "foo(Ljava/lang/Object;)V": { + "name": "foo", + "typeParameters": [], + "methodParameters": [ + { + "name": "object", + "type": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + } + ], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + } + }, + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + } + ] + } + ] + }, + "com.github.dart_lang.jnigen.regressions.R693$Child": { + "name": "R693$Child", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.regressions.R693", + "typeArguments": [ + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.regressions.R693$Child", + "typeArguments": [], + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "foo()Lcom/github/dart_lang/jnigen/regressions/R693$Child;": { + "name": "foo$1", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.regressions.R693$Child", + "typeArguments": [], + "nullability": "platform" + } + } + }, + "foo()Lcom/github/dart_lang/jnigen/regressions/R693;": { + "name": "foo", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.regressions.R693", + "typeArguments": [], + "nullability": "platform" + } + } + } + }, + "typeParameters": [] + }, + "com.github.dart_lang.jnigen.regressions.R693": { + "name": "R693", + "superClass": { + "kind": "declared", + "type": { + "binaryName": "java.lang.Object", + "typeArguments": [], + "nullability": "platform" + } + }, + "superInterfaces": [], + "fields": {}, + "methods": { + "()V": { + "name": "new$", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "primitive", + "type": { + "name": "void" + } + } + }, + "foo()Lcom/github/dart_lang/jnigen/regressions/R693;": { + "name": "foo", + "typeParameters": [], + "methodParameters": [], + "returnType": { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + } + }, + "typeParameters": [ + { + "name": "T", + "bounds": [ + { + "kind": "declared", + "type": { + "binaryName": "com.github.dart_lang.jnigen.regressions.R693", + "typeArguments": [ + { + "kind": "typeVariable", + "type": { + "name": "T", + "nullability": "platform" + } + } + ], + "nullability": "platform" + } + } + ] + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/pkgs/jnigen/lib/src/bindings/dart_generator.dart b/pkgs/jnigen/lib/src/bindings/dart_generator.dart index bee93d0dd1..324eb48de0 100644 --- a/pkgs/jnigen/lib/src/bindings/dart_generator.dart +++ b/pkgs/jnigen/lib/src/bindings/dart_generator.dart @@ -6,12 +6,12 @@ import 'dart:convert'; import 'dart:io'; import 'package:meta/meta.dart'; +import 'package:path/path.dart' as p; import '../config/config.dart'; import '../elements/elements.dart'; import '../logging/logging.dart'; import '../util/string_util.dart'; -import 'resolver.dart'; import 'visitor.dart'; /// Version of jnigen. Keep in sync with `pubspec.yaml` removing the `-wip` @@ -135,11 +135,60 @@ Map> _mergeMapValues(Map> a, Map> b) { /// calling, or whenever we don't want to have the `extends` keyword. /// * `fTypeClassesDef` refers to `JType $T, JType $U`. /// * `fTypeClassesCall` refers to `$T, $U` when calling the method. -class DartGenerator extends Visitor> { +class DartGenerator extends ElementVisitor> + with TopLevelVisitor { + @override + final stage = GenerationStage.dartGenerator; + final Config config; DartGenerator(this.config); + @override + Future visit(Classes node) async { + final fileGenerator = _FileGenerator(config); + await node.files.values.accept(fileGenerator).wait; + log.finest('Generated the bindings successfully.'); + + if (config.outputConfig.dartConfig.structure == + OutputStructure.singleFile) { + return; + } + + final root = config.outputConfig.dartConfig.path; + log.info('Using dart root = $root'); + { + final rootDirectory = Directory.fromUri(root); + if (rootDirectory.existsSync()) { + final files = rootDirectory.listSync(recursive: true).whereType(); + final filesToRemove = []; + for (final file in files) { + final stream = file.openRead(); + final firstLine = await stream + .transform(const Utf8Decoder()) + .transform(const LineSplitter()) + .first; + if (firstLine.startsWith('// AUTO GENERATED BY JNIGEN ')) { + log.fine('Removing old file ${file.path}'); + filesToRemove.add(file); + } else { + throw StateError(''' +A file that was not generated by JNIgen was found in ${root.path}: ${file.path}.'''); + } + } + await filesToRemove.map((file) => file.delete()).wait; + } + } + } +} + +typedef Resolver = String? Function(ClassDecl); + +class _FileGenerator extends ElementVisitor> { + final Config config; + + _FileGenerator(this.config); + // Do not change this. static const autoGeneratedNotice = '// AUTO GENERATED BY JNIGEN $version. ' 'DO NOT EDIT!\n'; @@ -148,7 +197,6 @@ import 'dart:core' show Object, String, bool, double, int; import 'dart:core' as $_core; import 'package:jni/_internal.dart' as $_jni; -import 'package:jni/jni.dart' as $_jni; '''; @@ -202,116 +250,57 @@ import 'package:jni/jni.dart' as $_jni; } @override - Future visit(Classes node) async { - final root = config.outputConfig.dartConfig.path; + Future visit(DartFile node) async { + log.warning(node.path); + final dartFile = + await File.fromUri(Uri.parse(node.path)).create(recursive: true); final preamble = config.preamble ?? ''; - if (config.outputConfig.dartConfig.structure == - OutputStructure.singleFile) { - final file = File.fromUri(root); - await file.create(recursive: true); - log.info('Generating bindings'); - final s = file.openWrite(); - s.writeln(autoGeneratedNotice); - s.writeln(preamble); - s.writeln(defaultLintSuppressions); - s.writeln(defaultImports); - final resolver = Resolver( - importedClasses: config.importedClasses, - currentClass: null, // Single file mode. - inputClassNames: node.decls.keys.toSet(), - ); - final classGenerator = _ClassGenerator(config, s, resolver); - for (final classDecl in node.decls.values) { - classDecl.accept(classGenerator); - } - await s.close(); - await _runDartFormat(file.path); - return; - } - final files = >{}; - final packages = >{}; - for (final classDecl in node.decls.values) { - final fileClass = Resolver.getFileClassName(classDecl.binaryName); - - files.putIfAbsent(fileClass, () => []); - files[fileClass]!.add(classDecl); - - packages.putIfAbsent(classDecl.packageName, () => {}); - packages[classDecl.packageName]!.add(fileClass.split('.').last); + final dartFileStream = dartFile.openWrite(); + dartFileStream.writeln(autoGeneratedNotice); + dartFileStream.writeln(preamble); + dartFileStream.writeln(defaultLintSuppressions); + dartFileStream.writeln(defaultImports); + for (final exportedFile in node.exports) { + final path = p.relative(exportedFile.path, from: node.path); + dartFileStream.writeln("export '$path';"); + } + final s = StringBuffer(); + + /// A map from the binary names of the imported classes to their import + /// prefix. + final fileToImportPrefix = { + DeclaredType.object.classDecl.file: _jni, + }; + String importPrefix(ClassDecl classDecl) { + if (classDecl.file == node) return ''; + fileToImportPrefix[classDecl.file] ??= 'i${fileToImportPrefix.length}\$_'; + return '${fileToImportPrefix[classDecl.file]}.'; } - log.info('Using dart root = $root'); - { - final rootDirectory = Directory.fromUri(root); - if (rootDirectory.existsSync()) { - final files = rootDirectory.listSync(recursive: true).whereType(); - final filesToRemove = []; - for (final file in files) { - final stream = file.openRead(); - final firstLine = await stream - .transform(const Utf8Decoder()) - .transform(const LineSplitter()) - .first; - if (firstLine.startsWith('// AUTO GENERATED BY JNIGEN ')) { - log.fine('Removing old file ${file.path}'); - filesToRemove.add(file); - } else { - throw StateError(''' -A file that was not generated by JNIgen was found in ${root.path}: ${file.path}.'''); - } - } - await filesToRemove.map((file) => file.delete()).wait; - } - } - for (var fileClassName in files.keys) { - final relativeFileName = '${fileClassName.replaceAll('.', '/')}.dart'; - final dartFileUri = root.resolve(relativeFileName); - final dartFile = await File.fromUri(dartFileUri).create(recursive: true); - log.fine('$fileClassName -> ${dartFile.path}'); - - final classesInFile = files[fileClassName]!; - final dartFileStream = dartFile.openWrite(); - dartFileStream.writeln(autoGeneratedNotice); - dartFileStream.writeln(preamble); - dartFileStream.writeln(defaultLintSuppressions); - dartFileStream.writeln(defaultImports); - final s = StringBuffer(); - final resolver = Resolver( - importedClasses: config.importedClasses, - currentClass: fileClassName, - inputClassNames: node.decls.keys.toSet(), - ); - final classGenerator = _ClassGenerator(config, s, resolver); - for (final classDecl in classesInFile) { - classDecl.accept(classGenerator); - } - dartFileStream.writeAll(resolver.importStrings, '\n'); - dartFileStream.writeln(s.toString()); - await dartFileStream.close(); + final classGenerator = _ClassGenerator(config, s, importPrefix); + for (final classDecl in node.classes.values) { + classDecl.accept(classGenerator); } - - // write _package.dart export files - for (var package in packages.keys) { - final dirUri = root.resolve('${package.replaceAll('.', '/')}/'); - final exportFileUri = dirUri.resolve('_package.dart'); - final exportFile = File.fromUri(exportFileUri); - exportFile.createSync(recursive: true); - final exports = - packages[package]!.map((cls) => "export '$cls.dart';").join('\n'); - exportFile.writeAsStringSync(autoGeneratedNotice + exports); + for (final MapEntry(key: importFile, value: importPrefix) + in fileToImportPrefix.entries) { + dartFileStream.writeln("import '${importFile.path}' as $importPrefix;"); } - await _runDartFormat(root.toFilePath()); - log.info('Completed.'); + dartFileStream.writeln(s.toString()); + await dartFileStream.close(); + await _runDartFormat(node.path); } } -/// Generates the Dart class definition, type class, and the array extension. -class _ClassGenerator extends Visitor { +/// Generates the Dart class definition and type class. +/// +/// In case of interfaces it also generates the classes related to interface +/// implementation. +class _ClassGenerator extends ElementVisitor { final Config config; final StringSink s; - final Resolver resolver; + final Resolver resolve; - _ClassGenerator(this.config, this.s, this.resolver); + _ClassGenerator(this.config, this.s, this.resolve); static const staticTypeGetter = 'type'; static const instanceTypeGetter = '\$$staticTypeGetter'; @@ -319,7 +308,7 @@ class _ClassGenerator extends Visitor { void generateFieldsAndMethods(ClassDecl node, String classRef) { final fieldGenerator = _FieldGenerator( config, - resolver, + resolve, s, isTopLevel: node.isTopLevel, classRef: classRef, @@ -329,7 +318,7 @@ class _ClassGenerator extends Visitor { } final methodGenerator = _MethodGenerator( config, - resolver, + resolve, s, isTopLevel: node.isTopLevel, classRef: classRef, @@ -365,7 +354,7 @@ ${modifier}final $classRef = $_jni.JClass.forName(r'$internalName'); // Class definition. final name = node.finalName; final superName = node.superclass!.accept( - _TypeGenerator(resolver, includeNullability: false), + _TypeGenerator(resolve, includeNullability: false), ); final implClassName = '\$$name'; final typeParamsDef = node.allTypeParams @@ -390,11 +379,11 @@ ${modifier}final $classRef = $_jni.JClass.forName(r'$internalName'); final ctorTypeClassesDef = typeParams .map((typeParam) => 'this.$typeParam,') .join(_newLine(depth: 2)); - final superClass = node.classDecl.superclass! as DeclaredType; + final superClass = node.superclass! as DeclaredType; final superTypeClassesCall = superClass.classDecl.isObject ? '' : superClass.params - .accept(_TypeClassGenerator(resolver)) + .accept(_TypeClassGenerator(resolve)) .map((typeClass) => '${typeClass.name},') .join(_newLine(depth: 2)); s.write(''' @@ -465,9 +454,9 @@ class $name$typeParamsDef extends $superName { // Operators for (final MapEntry(key: operator, value: method) in node.operators.entries) { - method.accept(_OperatorGenerator(resolver, s, operator: operator)); + method.accept(_OperatorGenerator(resolve, s, operator: operator)); } - node.compareTo?.accept(_ComparatorGenerator(resolver, s)); + node.compareTo?.accept(_ComparatorGenerator(resolve, s)); if (node.declKind == DeclKind.interfaceKind) { s.write(''' @@ -504,7 +493,7 @@ class $name$typeParamsDef extends $superName { final \$d = \$i.methodDescriptor.toDartString(releaseOriginal: true); final \$a = \$i.args; '''); - final proxyMethodIf = _InterfaceMethodIf(resolver, s); + final proxyMethodIf = _InterfaceMethodIf(resolve, s); for (final method in node.methods) { method.accept(proxyMethodIf); } @@ -537,7 +526,7 @@ class $name$typeParamsDef extends $superName { [ '''); final interfaceAsyncMethod = _InterfaceIfAsyncMethod( - resolver, + resolve, s, implClassName: implClassName, ); @@ -591,7 +580,7 @@ class $name$typeParamsDef extends $superName { ...typeParams.map( (typeParam) => 'required $_jType<\$$typeParam> $typeParam,', ), - ...node.methods.accept(_AbstractImplFactoryArg(resolver)), + ...node.methods.accept(_AbstractImplFactoryArg(resolve)), ].join(_newLine(depth: 2)).encloseIfNotEmpty('{', '}'); s.write(''' abstract base mixin class $implClassName$typeParamsDef { @@ -602,7 +591,7 @@ abstract base mixin class $implClassName$typeParamsDef { $typeClassGetters '''); - final abstractImplMethod = _AbstractImplMethod(resolver, s); + final abstractImplMethod = _AbstractImplMethod(resolve, s); for (final method in node.methods) { method.accept(abstractImplMethod); } @@ -612,7 +601,7 @@ abstract base mixin class $implClassName$typeParamsDef { // This is for passing closures instead of implementing the class. final concreteCtorArgs = [ ...typeParams.map((typeParam) => 'required this.$typeParam,'), - ...node.methods.accept(_ConcreteImplClosureCtorArg(resolver)), + ...node.methods.accept(_ConcreteImplClosureCtorArg(resolve)), ].join(_newLine(depth: 2)).encloseIfNotEmpty('{', '}'); final setClosures = node.methods .map((method) => '_${method.finalName} = ${method.finalName}') @@ -636,12 +625,12 @@ final class _$implClassName$typeParamsDef with $implClassName$typeParamsCall { $typeClassesDef '''); - final concreteClosureDef = _ConcreteImplClosureDef(resolver, s); + final concreteClosureDef = _ConcreteImplClosureDef(resolve, s); for (final method in node.methods) { method.accept(concreteClosureDef); } s.writeln(); - final concreteMethodDef = _ConcreteImplMethod(resolver, s); + final concreteMethodDef = _ConcreteImplMethod(resolve, s); for (final method in node.methods) { method.accept(concreteMethodDef); } @@ -654,7 +643,7 @@ final class _$implClassName$typeParamsDef with $implClassName$typeParamsCall { final typeClassesCall = typeParams.map((typeParam) => '$typeParam,').join(_newLine(depth: 2)); final signature = node.signature; - final superType = superClass.accept(_TypeClassGenerator(resolver)).name; + final superType = superClass.accept(_TypeClassGenerator(resolve)).name; final hashCodeTypeClasses = typeParams.join(', '); final equalityTypeClasses = typeParams .map((typeParam) => ' &&\n $typeParam == other.$typeParam') @@ -678,7 +667,7 @@ final class _$implClassName$typeParamsDef with $implClassName$typeParamsCall { ) .toList(), )..classDecl = node) - .accept(_TypeClassGenerator(resolver)) + .accept(_TypeClassGenerator(resolve)) .name; final nullable = isNullable ? '?' : ''; s.write(''' @@ -747,7 +736,7 @@ final class $typeClassName$typeParamsDef extends $_jType<$name$typeParamsCall$nu } /// Generates the JavaDoc comments. -class _DocGenerator extends Visitor { +class _DocGenerator extends ElementVisitor { final StringSink s; final int depth; @@ -776,8 +765,8 @@ $indent/// $comments } /// Generates the user-facing Dart type. -class _TypeGenerator extends TypeVisitor { - final Resolver? resolver; +class _TypeGenerator extends TypeVisitor with DefaultNonPrimitive { + final Resolver resolve; /// Whether the top-type of the current type being visited is nullable. /// @@ -796,7 +785,7 @@ class _TypeGenerator extends TypeVisitor { final bool arrayType; const _TypeGenerator( - this.resolver, { + this.resolve, { this.forInterfaceImplementation = false, this.typeErasure = false, this.includeNullability = true, @@ -810,7 +799,7 @@ class _TypeGenerator extends TypeVisitor { final nullable = includeNullability && node.isNullable && isTopTypeNullable ? '?' : ''; final typeGenerator = _TypeGenerator( - resolver, + resolve, forInterfaceImplementation: forInterfaceImplementation, typeErasure: forInterfaceImplementation, includeNullability: true, @@ -835,7 +824,7 @@ class _TypeGenerator extends TypeVisitor { final allTypeParams = node.mapTypeParameters( (isNullable, definedType) { return definedType.accept(_TypeGenerator( - resolver, + resolve, forInterfaceImplementation: forInterfaceImplementation, typeErasure: forInterfaceImplementation, includeNullability: true, @@ -846,7 +835,7 @@ class _TypeGenerator extends TypeVisitor { ); final typeParams = allTypeParams.join(', ').encloseIfNotEmpty('<', '>'); - final prefix = resolver?.resolvePrefix(node.classDecl) ?? ''; + final prefix = resolve(node.classDecl); return '$prefix${node.classDecl.finalName}$typeParams$nullable'; } @@ -884,7 +873,7 @@ class _TypeGenerator extends TypeVisitor { return super.visitWildcard(node); } final typeGenerator = _TypeGenerator( - resolver, + resolve, arrayType: arrayType, forInterfaceImplementation: forInterfaceImplementation, includeNullability: @@ -911,7 +900,8 @@ class _TypeClass { } /// Generates the type class. -class _TypeClassGenerator extends TypeVisitor<_TypeClass> { +class _TypeClassGenerator extends TypeVisitor<_TypeClass> + with DefaultNonPrimitive { final bool isConst; /// Whether the top-type of the current type being visited is nullable. @@ -933,10 +923,10 @@ class _TypeClassGenerator extends TypeVisitor<_TypeClass> { final bool includeNullability; - final Resolver resolver; + final Resolver resolve; _TypeClassGenerator( - this.resolver, { + this.resolve, { this.isConst = true, this.boxPrimitives = false, this.forInterfaceImplementation = false, @@ -949,7 +939,7 @@ class _TypeClassGenerator extends TypeVisitor<_TypeClass> { _TypeClass visitArrayType(ArrayType node) { final innerTypeClass = node.elementType.accept( _TypeClassGenerator( - resolver, + resolve, isConst: false, boxPrimitives: false, forInterfaceImplementation: forInterfaceImplementation, @@ -960,7 +950,7 @@ class _TypeClassGenerator extends TypeVisitor<_TypeClass> { ); final innerType = node.elementType.accept( _TypeGenerator( - resolver, + resolve, forInterfaceImplementation: forInterfaceImplementation, // Do type erasure for interface implementation. typeErasure: forInterfaceImplementation, @@ -993,7 +983,7 @@ class _TypeClassGenerator extends TypeVisitor<_TypeClass> { final allTypeClasses = node.mapTypeParameters( (isNullable, definedType) { return definedType.accept(_TypeClassGenerator( - resolver, + resolve, isConst: false, boxPrimitives: false, forInterfaceImplementation: forInterfaceImplementation, @@ -1024,7 +1014,7 @@ class _TypeClassGenerator extends TypeVisitor<_TypeClass> { (isNullable, definedType) { return definedType.accept( _TypeGenerator( - resolver, + resolve, forInterfaceImplementation: forInterfaceImplementation, // Do type erasure for interface implementation. typeErasure: forInterfaceImplementation, @@ -1034,7 +1024,7 @@ class _TypeClassGenerator extends TypeVisitor<_TypeClass> { }, ); final typeArgs = typeArgsList.join(', ').encloseIfNotEmpty('<', '>'); - final prefix = resolver.resolvePrefix(node.classDecl); + final prefix = resolve(node.classDecl); return _TypeClass('$ifConst$prefix$type$typeArgs($args)', canBeConst); } @@ -1083,7 +1073,7 @@ class _TypeClassGenerator extends TypeVisitor<_TypeClass> { return super.visitWildcard(node); } final typeClassGenerator = _TypeClassGenerator( - resolver, + resolve, boxPrimitives: boxPrimitives, forInterfaceImplementation: forInterfaceImplementation, includeNullability: @@ -1105,7 +1095,7 @@ class _TypeClassGenerator extends TypeVisitor<_TypeClass> { } } -class _TypeParamDef extends Visitor { +class _TypeParamDef extends ElementVisitor { const _TypeParamDef(); @override @@ -1117,10 +1107,10 @@ class _TypeParamDef extends Visitor { } } -class _JniResultGetter extends TypeVisitor { - final Resolver resolver; +class _JniResultGetter extends TypeVisitor with DefaultNonPrimitive { + final Resolver resolve; - _JniResultGetter(this.resolver); + _JniResultGetter(this.resolve); @override String visitPrimitiveType(PrimitiveType node) { @@ -1132,8 +1122,8 @@ class _JniResultGetter extends TypeVisitor { @override String visitNonPrimitiveType(ReferredType node) { - final typeClass = node.accept(_TypeClassGenerator(resolver)).name; - final type = node.accept(_TypeGenerator(resolver)); + final typeClass = node.accept(_TypeClassGenerator(resolve)).name; + final type = node.accept(_TypeGenerator(resolve)); return 'object<$type>($typeClass)'; } } @@ -1143,7 +1133,7 @@ class _JniResultGetter extends TypeVisitor { /// When `isFfi` is `true`, it generates the ffi type signature for vararg. /// /// For example `ffi.Int32` is an ffi type signature while `int` is a Dart one. -class _TypeSig extends TypeVisitor { +class _TypeSig extends TypeVisitor with DefaultNonPrimitive { final bool isFfi; const _TypeSig({required this.isFfi}); @@ -1161,7 +1151,7 @@ class _TypeSig extends TypeVisitor { } } -class _ToNativeSuffix extends TypeVisitor { +class _ToNativeSuffix extends TypeVisitor with DefaultNonPrimitive { const _ToNativeSuffix(); @override @@ -1178,16 +1168,16 @@ class _ToNativeSuffix extends TypeVisitor { } } -class _FieldGenerator extends Visitor { +class _FieldGenerator extends ElementVisitor { final Config config; - final Resolver resolver; + final Resolver resolve; final StringSink s; final bool isTopLevel; final String classRef; const _FieldGenerator( this.config, - this.resolver, + this.resolve, this.s, { required this.isTopLevel, required this.classRef, @@ -1211,14 +1201,14 @@ ${modifier}final _id_$name = String dartOnlyGetter(Field node) { final name = node.finalName; final self = node.isStatic ? classRef : _self; - final type = node.type.accept(_TypeClassGenerator(resolver)).name; + final type = node.type.accept(_TypeClassGenerator(resolve)).name; return '_id_$name.get($self, $type)'; } String dartOnlySetter(Field node) { final name = node.finalName; final self = node.isStatic ? classRef : _self; - final type = node.type.accept(_TypeClassGenerator(resolver)).name; + final type = node.type.accept(_TypeClassGenerator(resolve)).name; return '_id_$name.set($self, $type, value)'; } @@ -1252,7 +1242,7 @@ ${modifier}final _id_$name = final name = node.finalName; final ifStatic = node.isStatic && !isTopLevel ? 'static ' : ''; - final type = node.type.accept(_TypeGenerator(resolver)); + final type = node.type.accept(_TypeGenerator(resolve)); s.write('$ifStatic$type get $name => '); s.write(dartOnlyGetter(node)); s.writeln(';\n'); @@ -1267,7 +1257,7 @@ ${modifier}final _id_$name = } } -class _MethodTypeSig extends Visitor { +class _MethodTypeSig extends ElementVisitor { final bool isFfi; const _MethodTypeSig({required this.isFfi}); @@ -1293,16 +1283,16 @@ class _MethodTypeSig extends Visitor { } /// Generates Dart bindings for Java methods. -class _MethodGenerator extends Visitor { +class _MethodGenerator extends ElementVisitor { final Config config; - final Resolver resolver; + final Resolver resolve; final StringSink s; final bool isTopLevel; final String classRef; const _MethodGenerator( this.config, - this.resolver, + this.resolve, this.s, { required this.isTopLevel, required this.classRef, @@ -1358,7 +1348,7 @@ ${modifier}final _$name = $_protectedExtension '_id_$name as $_jni.JMethodIDPtr', ...node.params.accept(const _ParamCall()), ].join(', '); - final resultGetter = node.returnType.accept(_JniResultGetter(resolver)); + final resultGetter = node.returnType.accept(_JniResultGetter(resolve)); return '_$name($params).$resultGetter'; } @@ -1385,7 +1375,7 @@ ${modifier}final _$name = $_protectedExtension // Used for inferring the type parameter from the given parameters. final typeLocators = node.params - .accept(_ParamTypeLocator(resolver: resolver)) + .accept(_ParamTypeLocator(resolve: resolve)) .fold(>{}, _mergeMapValues).map( (key, value) => MapEntry(key, value.delimited(', ').encloseIfNotEmpty('[', ']')), @@ -1414,7 +1404,7 @@ ${modifier}final _$name = $_protectedExtension final className = node.classDecl.finalName; final name = node.finalName; final ctorName = name == 'new\$' ? className : '$className.$name'; - final paramsDef = node.params.accept(_ParamDef(resolver)).delimited(', '); + final paramsDef = node.params.accept(_ParamDef(resolve)).delimited(', '); final typeParamsCall = node.classDecl.allTypeParams .map((typeParam) => '$_typeParamPrefix${typeParam.name}') .join(', ') @@ -1449,10 +1439,10 @@ ${modifier}final _$name = $_protectedExtension final name = node.finalName; final returnType = isSuspendFun(node) ? '$_core.Future<' - '${node.asyncReturnType!.accept(_TypeGenerator(resolver))}>' - : node.returnType.accept(_TypeGenerator(resolver)); + '${node.asyncReturnType!.accept(_TypeGenerator(resolve))}>' + : node.returnType.accept(_TypeGenerator(resolve)); final ifStatic = node.isStatic && !isTopLevel ? 'static ' : ''; - final defArgs = node.params.accept(_ParamDef(resolver)).toList(); + final defArgs = node.params.accept(_ParamDef(resolve)).toList(); final typeClassDef = node.typeParams .map( (typeParam) => typeParam.accept( @@ -1474,9 +1464,9 @@ ${modifier}final _$name = $_protectedExtension final callExpr = methodCall(node); if (isSuspendFun(node)) { final returningType = - node.asyncReturnType!.accept(_TypeGenerator(resolver)); + node.asyncReturnType!.accept(_TypeGenerator(resolve)); final returningTypeClass = - node.asyncReturnType!.accept(_TypeClassGenerator(resolver)).name; + node.asyncReturnType!.accept(_TypeClassGenerator(resolve)).name; final isNullable = node.asyncReturnType!.isNullable; final continuation = node.params.last.finalName; s.write('''async { @@ -1587,7 +1577,7 @@ ${modifier}final _$name = $_protectedExtension /// ```dart /// void bar(..., {required JObjType $T}) => ... /// ``` -class _MethodTypeClassDef extends Visitor { +class _MethodTypeClassDef extends ElementVisitor { final bool isRequired; const _MethodTypeClassDef({required this.isRequired}); @@ -1608,7 +1598,7 @@ class _MethodTypeClassDef extends Visitor { /// Foo(..., {required this.$T}) => ... /// } /// ``` -class _CtorTypeClassDef extends Visitor { +class _CtorTypeClassDef extends ElementVisitor { final bool isRequired; const _CtorTypeClassDef({required this.isRequired}); @@ -1626,17 +1616,17 @@ class _CtorTypeClassDef extends Visitor { /// ```dart /// void bar(Foo foo) => ... /// ``` -class _ParamDef extends Visitor { - final Resolver resolver; +class _ParamDef extends ElementVisitor { + final Resolver resolve; final bool methodGenericErasure; - const _ParamDef(this.resolver, {this.methodGenericErasure = false}); + const _ParamDef(this.resolve, {this.methodGenericErasure = false}); @override String visit(Param node) { final type = node.type.accept( _TypeGenerator( - resolver, + resolve, forInterfaceImplementation: methodGenericErasure, ), ); @@ -1653,7 +1643,7 @@ class _ParamDef extends Visitor { /// ```dart /// final _foo = foo.reference; /// ``` -class _ParamReference extends Visitor { +class _ParamReference extends ElementVisitor { const _ParamReference(); @override @@ -1674,7 +1664,7 @@ class _ParamReference extends Visitor { /// ```dart /// void bar(Foo foo) => _bar(foo.reference.pointer); /// ``` -class _ParamCall extends Visitor { +class _ParamCall extends ElementVisitor { const _ParamCall(); @override @@ -1736,17 +1726,18 @@ class OutsideInBuffer { /// ((((a.$type as JArrayType).elementType) as $JMapType).V) /// as JObjType<$T> /// ``` -class _ParamTypeLocator extends Visitor>> { - final Resolver resolver; +class _ParamTypeLocator + extends ElementVisitor>> { + final Resolver resolve; - _ParamTypeLocator({required this.resolver}); + _ParamTypeLocator({required this.resolve}); @override Map> visit(Param node) { if (node.isNullable) { return {}; } - return node.type.accept(_TypeVarLocator(resolver: resolver)).map( + return node.type.accept(_TypeVarLocator(resolve: resolve)).map( (key, value) => MapEntry( key, value @@ -1760,21 +1751,16 @@ class _ParamTypeLocator extends Visitor>> { } class _TypeVarLocator extends TypeVisitor>> { - final Resolver resolver; - - _TypeVarLocator({required this.resolver}); + final Resolver resolve; - @override - Map> visitNonPrimitiveType(ReferredType node) { - return {}; - } + _TypeVarLocator({required this.resolve}); @override Map> visitWildcard(Wildcard node) { // TODO(https://github.com/dart-lang/native/issues/701): Support wildcards. if (node.superBound != null || node.extendsBound == null) { // Dart does not support `* super T` wildcards. Fall back to Object?. - return super.visitWildcard(node); + return {}; } return node.extendsBound!.accept(this); } @@ -1790,11 +1776,11 @@ class _TypeVarLocator extends TypeVisitor>> { Map> visitDeclaredType(DeclaredType node) { if (node.classDecl.isObject) { // The class is not generated, fall back to `JObject`. - return super.visitDeclaredType(node); + return {}; } final offset = node.classDecl.allTypeParams.length - node.params.length; final result = >{}; - final prefix = resolver.resolvePrefix(node.classDecl); + final prefix = resolve(node.classDecl); final typeClass = '$prefix${node.classDecl.typeClassName}'; final typeClassParams = List.filled( node.classDecl.allTypeParams.length, @@ -1831,20 +1817,20 @@ class _TypeVarLocator extends TypeVisitor>> { } /// Method defintion for Impl abstract class used for interface implementation. -class _AbstractImplMethod extends Visitor { - final Resolver resolver; +class _AbstractImplMethod extends ElementVisitor { + final Resolver resolve; final StringSink s; - _AbstractImplMethod(this.resolver, this.s); + _AbstractImplMethod(this.resolve, this.s); @override void visit(Method node) { final returnType = node.returnType.accept( - _TypeGenerator(resolver, forInterfaceImplementation: true), + _TypeGenerator(resolve, forInterfaceImplementation: true), ); final name = node.finalName; final args = node.params - .accept(_ParamDef(resolver, methodGenericErasure: true)) + .accept(_ParamDef(resolve, methodGenericErasure: true)) .join(', '); s.writeln(' $returnType $name($args);'); if (returnType == 'void') { @@ -1854,20 +1840,20 @@ class _AbstractImplMethod extends Visitor { } /// Closure defintion for concrete Impl class used for interface implementation. -class _ConcreteImplClosureDef extends Visitor { - final Resolver resolver; +class _ConcreteImplClosureDef extends ElementVisitor { + final Resolver resolve; final StringSink s; - _ConcreteImplClosureDef(this.resolver, this.s); + _ConcreteImplClosureDef(this.resolve, this.s); @override void visit(Method node) { final returnType = node.returnType.accept( - _TypeGenerator(resolver, forInterfaceImplementation: true), + _TypeGenerator(resolve, forInterfaceImplementation: true), ); final name = node.finalName; final args = node.params - .accept(_ParamDef(resolver, methodGenericErasure: true)) + .accept(_ParamDef(resolve, methodGenericErasure: true)) .join(', '); s.writeln(' final $returnType Function($args) _$name;'); if (returnType == 'void') { @@ -1878,19 +1864,19 @@ class _ConcreteImplClosureDef extends Visitor { /// Closure argument for the factory of the implementation's abstract class. /// Used for interface implementation. -class _AbstractImplFactoryArg extends Visitor { - final Resolver resolver; +class _AbstractImplFactoryArg extends ElementVisitor { + final Resolver resolve; - _AbstractImplFactoryArg(this.resolver); + _AbstractImplFactoryArg(this.resolve); @override String visit(Method node) { final returnType = node.returnType.accept( - _TypeGenerator(resolver, forInterfaceImplementation: true), + _TypeGenerator(resolve, forInterfaceImplementation: true), ); final name = node.finalName; final args = node.params - .accept(_ParamDef(resolver, methodGenericErasure: true)) + .accept(_ParamDef(resolve, methodGenericErasure: true)) .join(', '); final functionArg = 'required $returnType Function($args) $name,'; if (node.returnType.name == 'void') { @@ -1902,19 +1888,19 @@ class _AbstractImplFactoryArg extends Visitor { /// Closure argument for concrete Impl class constructor. /// Used for interface implementation. -class _ConcreteImplClosureCtorArg extends Visitor { - final Resolver resolver; +class _ConcreteImplClosureCtorArg extends ElementVisitor { + final Resolver resolve; - _ConcreteImplClosureCtorArg(this.resolver); + _ConcreteImplClosureCtorArg(this.resolve); @override String visit(Method node) { final returnType = node.returnType.accept( - _TypeGenerator(resolver, forInterfaceImplementation: true), + _TypeGenerator(resolve, forInterfaceImplementation: true), ); final name = node.finalName; final args = node.params - .accept(_ParamDef(resolver, methodGenericErasure: true)) + .accept(_ParamDef(resolve, methodGenericErasure: true)) .join(', '); final functionArg = 'required $returnType Function($args) $name,'; if (node.returnType.name == 'void') { @@ -1925,20 +1911,20 @@ class _ConcreteImplClosureCtorArg extends Visitor { } /// Method defintion for concrete Impl class used for interface implementation. -class _ConcreteImplMethod extends Visitor { - final Resolver resolver; +class _ConcreteImplMethod extends ElementVisitor { + final Resolver resolve; final StringSink s; - _ConcreteImplMethod(this.resolver, this.s); + _ConcreteImplMethod(this.resolve, this.s); @override void visit(Method node) { final returnType = node.returnType.accept( - _TypeGenerator(resolver, forInterfaceImplementation: true), + _TypeGenerator(resolve, forInterfaceImplementation: true), ); final name = node.finalName; final argsDef = node.params - .accept(_ParamDef(resolver, methodGenericErasure: true)) + .accept(_ParamDef(resolve, methodGenericErasure: true)) .join(', '); final argsCall = node.params.map((param) => param.finalName).join(', '); s.write(''' @@ -1949,24 +1935,24 @@ class _ConcreteImplMethod extends Visitor { } /// The if statement to check which method has been called from the proxy class. -class _InterfaceMethodIf extends Visitor { - final Resolver resolver; +class _InterfaceMethodIf extends ElementVisitor { + final Resolver resolve; final StringSink s; - _InterfaceMethodIf(this.resolver, this.s); + _InterfaceMethodIf(this.resolve, this.s); @override void visit(Method node) { final isVoid = node.returnType.name == 'void'; - final signature = node.javaSig; + final identifier = node.javaSig; final saveResult = isVoid ? '' : 'final \$r = '; final name = node.finalName; s.write(''' - if (\$d == r'$signature') { + if (\$d == r'$identifier') { ${saveResult}_\$impls[\$p]!.$name( '''); for (var i = 0; i < node.params.length; ++i) { - node.params[i].accept(_InterfaceParamCast(resolver, s, paramIndex: i)); + node.params[i].accept(_InterfaceParamCast(resolve, s, paramIndex: i)); } const returnBox = _InterfaceReturnBox(); s.write(''' @@ -1978,12 +1964,12 @@ class _InterfaceMethodIf extends Visitor { } /// The if statement within the async methods list to conditionally add methods. -class _InterfaceIfAsyncMethod extends Visitor { - final Resolver resolver; +class _InterfaceIfAsyncMethod extends ElementVisitor { + final Resolver resolve; final StringSink s; final String implClassName; - _InterfaceIfAsyncMethod(this.resolver, this.s, {required this.implClassName}); + _InterfaceIfAsyncMethod(this.resolve, this.s, {required this.implClassName}); @override void visit(Method node) { @@ -2000,19 +1986,19 @@ class _InterfaceIfAsyncMethod extends Visitor { /// Generates casting to the correct parameter type from the list of JObject /// arguments received from the call to the proxy class. -class _InterfaceParamCast extends Visitor { - final Resolver resolver; +class _InterfaceParamCast extends ElementVisitor { + final Resolver resolve; final StringSink s; final int paramIndex; - _InterfaceParamCast(this.resolver, this.s, {required this.paramIndex}); + _InterfaceParamCast(this.resolve, this.s, {required this.paramIndex}); @override void visit(Param node) { final typeClass = node.type .accept( _TypeClassGenerator( - resolver, + resolve, boxPrimitives: true, forInterfaceImplementation: true, includeNullability: false, @@ -2043,7 +2029,7 @@ class _InterfaceParamCast extends Visitor { /// /// For example `$r.toJInteger().reference.toPointer()` when the return /// type is `integer`. -class _InterfaceReturnBox extends TypeVisitor { +class _InterfaceReturnBox extends TypeVisitor with DefaultNonPrimitive { const _InterfaceReturnBox(); @override @@ -2064,7 +2050,7 @@ class _InterfaceReturnBox extends TypeVisitor { } } -class _CallMethodName extends Visitor { +class _CallMethodName extends ElementVisitor { const _CallMethodName(); @override @@ -2082,19 +2068,19 @@ class _CallMethodName extends Visitor { } } -class _OperatorGenerator extends Visitor { - final Resolver resolver; +class _OperatorGenerator extends ElementVisitor { + final Resolver resolve; final StringSink s; final Operator operator; - _OperatorGenerator(this.resolver, this.s, {required this.operator}); + _OperatorGenerator(this.resolve, this.s, {required this.operator}); @override void visit(Method node) { final returnType = operator.returnsVoid ? 'void' - : node.returnType.accept(_TypeGenerator(resolver)); - final paramsDef = node.params.accept(_ParamDef(resolver)).join(', '); + : node.returnType.accept(_TypeGenerator(resolve)); + final paramsDef = node.params.accept(_ParamDef(resolve)).join(', '); final paramsCall = node.params.map((param) => param.finalName).join(', '); s.write(''' $returnType operator ${operator.dartSymbol}($paramsDef) { @@ -2104,15 +2090,15 @@ class _OperatorGenerator extends Visitor { } } -class _ComparatorGenerator extends Visitor { - final Resolver resolver; +class _ComparatorGenerator extends ElementVisitor { + final Resolver resolve; final StringSink s; - _ComparatorGenerator(this.resolver, this.s); + _ComparatorGenerator(this.resolve, this.s); @override void visit(Method node) { - final paramsDef = node.params.accept(_ParamDef(resolver)).join(', '); + final paramsDef = node.params.accept(_ParamDef(resolve)).join(', '); final paramsCall = node.params.map((param) => param.finalName).join(', '); final name = node.finalName; s.write(''' diff --git a/pkgs/jnigen/lib/src/bindings/excluder.dart b/pkgs/jnigen/lib/src/bindings/excluder.dart deleted file mode 100644 index fb4624a635..0000000000 --- a/pkgs/jnigen/lib/src/bindings/excluder.dart +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import '../config/config.dart'; -import '../elements/elements.dart'; -import '../logging/logging.dart'; -import 'visitor.dart'; - -extension on ClassMember { - bool get isPrivate => !isPublic; -} - -// TODO(https://github.com/dart-lang/native/issues/1164): Kotlin compiler -// appends the method name with a dash and a hash code when arguments contain -// inline classes. This is because inline classes do not have any runtime type -// and the typical operator overloading supported by JVM cannot work for them. -// -// Once we support inline classes, we can relax the following constraints. -final _validDartIdentifier = RegExp(r'^[a-zA-Z_$][a-zA-Z0-9_$]*$'); - -extension on String { - bool get isInvalidDartIdentifier => - !_validDartIdentifier.hasMatch(this) && - this != '' && - this != ''; -} - -class Excluder extends Visitor with TopLevelVisitor { - @override - final GenerationStage stage = GenerationStage.excluder; - - final Config config; - - const Excluder(this.config); - - @override - void visit(Classes node) { - node.decls.removeWhere((_, classDecl) { - final excluded = classDecl.isPrivate || classDecl.isExcluded; - if (excluded) { - log.fine('Excluded class ${classDecl.binaryName}'); - } - if (classDecl.name.isInvalidDartIdentifier) { - log.warning('Excluded class ${classDecl.binaryName}: the name is not a' - ' valid Dart identifer'); - return true; - } - return excluded; - }); - final classExcluder = _ClassExcluder(config); - for (final classDecl in node.decls.values) { - classDecl.accept(classExcluder); - } - } -} - -class _ClassExcluder extends Visitor { - final Config config; - - _ClassExcluder(this.config); - - @override - void visit(ClassDecl node) { - node.methods = node.methods.where((method) { - final isExcluded = method.userDefinedIsExcluded; - final isPrivate = method.isPrivate; - final isAbstractCtor = method.isConstructor && node.isAbstract; - final isBridgeMethod = method.isSynthetic && method.isBridge; - final excluded = - isPrivate || isAbstractCtor || isBridgeMethod || isExcluded; - if (excluded) { - log.fine('Excluded method ${node.binaryName}#${method.name}'); - } - if (method.name.isInvalidDartIdentifier) { - log.warning( - 'Excluded method ${node.binaryName}#${method.name}: the name is not' - ' a valid Dart identifer'); - return false; - } - return !excluded; - }).toList(); - node.fields = node.fields.where((field) { - final excluded = field.isExcluded || field.isPrivate; - if (excluded) { - log.fine('Excluded field ${node.binaryName}#${field.name}'); - } - if (field.name.isInvalidDartIdentifier) { - log.warning( - 'Excluded field ${node.binaryName}#${field.name}: the name is not' - ' a valid Dart identifer'); - return false; - } - return !excluded; - }).toList(); - } -} diff --git a/pkgs/jnigen/lib/src/bindings/exporter.dart b/pkgs/jnigen/lib/src/bindings/exporter.dart new file mode 100644 index 0000000000..abd192ee21 --- /dev/null +++ b/pkgs/jnigen/lib/src/bindings/exporter.dart @@ -0,0 +1,209 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:convert'; +import 'dart:io'; + +import 'package:pub_semver/pub_semver.dart'; + +import '../config/config.dart'; +import '../elements/elements.dart'; +import '../elements/stability_models.dart'; +import '../logging/logging.dart'; +import 'visitor.dart'; + +final _version = Version(1, 0, 0); + +extension> on Iterable { + Map acceptAndMap(ElementVisitor visitor, + {required String Function(T) key}) { + final map = {}; + for (final element in this) { + map[key(element)] = element.accept(visitor); + } + return map; + } +} + +/// Generates the JSON used for API stability and importing. +class Exporter extends ElementVisitor> + with TopLevelVisitor { + @override + final stage = GenerationStage.exporter; + + final Config config; + + Exporter(this.config); + + @override + Future visit(Classes node) async { + final exportFileUri = config.outputConfig.symbolsConfig?.path ?? + Uri.file('jnigen_symbols.json'); + + // FIXME: add package name + final apiStabilityInfo = StabilityInfo( + formatVersion: _version, + packageName: 'tbd', + files: node.files.values + .acceptAndMap(_fileExporter, key: (file) => file.path), + ); + + final exportFile = File.fromUri(exportFileUri); + final sink = exportFile.openWrite(); + await sink.addStream( + Stream.value(apiStabilityInfo).transform(JsonUtf8Encoder(' ').cast())); + await sink.close(); + } +} + +const _fileExporter = _FileExporter(); + +class _FileExporter extends ElementVisitor { + const _FileExporter(); + + @override + StabilityFile visit(DartFile node) { + return StabilityFile( + classes: node.classes.values + .acceptAndMap(_classExporter, key: (cls) => cls.binaryName), + ); + } +} + +const _classExporter = _ClassExporter(); + +class _ClassExporter extends ElementVisitor { + const _ClassExporter(); + + @override + StabilityClass visit(ClassDecl node) { + return StabilityClass( + name: node.finalName!, + superClass: node.superclass!.accept(_typeExporter), + superInterfaces: node.interfaces.accept(_typeExporter).toList(), + fields: + node.fields.acceptAndMap(_fieldExporter, key: (field) => field.name), + methods: node.methods + .acceptAndMap(_methodExporter, key: (method) => method.javaSig), + typeParameters: node.allTypeParams.accept(_typeParamExporter).toList(), + ); + } +} + +const _fieldExporter = _FieldExporter(); + +class _FieldExporter extends ElementVisitor { + const _FieldExporter(); + + @override + StabilityField visit(Field node) { + return StabilityField( + name: node.finalName!, + type: node.type.accept(_typeExporter), + ); + } +} + +const _methodExporter = _MethodExporter(); + +class _MethodExporter extends ElementVisitor { + const _MethodExporter(); + + @override + StabilityMethod visit(Method node) { + if (node.finalName == null) { + log.warning( + '${node.classDecl.binaryName}#${node.javaSig} has a null finalName'); + } + return StabilityMethod( + name: node.finalName ?? 'NULL', + typeParameters: node.typeParams.accept(_typeParamExporter).toList(), + methodParameters: node.params.accept(_paramExporter).toList(), + returnType: node.returnType.accept(_typeExporter), + ); + } +} + +const _paramExporter = _ParamExporter(); + +class _ParamExporter extends ElementVisitor { + const _ParamExporter(); + + @override + StabilityMethodParameter visit(Param node) { + return StabilityMethodParameter( + name: node.finalName!, + type: node.type.accept(_typeExporter), + ); + } +} + +const _typeParamExporter = _TypeParamExporter(); + +class _TypeParamExporter + extends ElementVisitor { + const _TypeParamExporter(); + + @override + StabilityTypeParameter visit(TypeParam node) { + return StabilityTypeParameter( + name: node.name, + bounds: node.bounds.accept(_typeExporter).toList(), + ); + } +} + +const _typeExporter = _TypeExporter(); + +class _TypeExporter extends TypeVisitor { + const _TypeExporter(); + + Nullability nullabilityFromType(ReferredType type) { + // TODO(https://github.com/dart-lang/native/issues/2356): Also refactor this + // in the internal representation. + if (type.hasNullable) return Nullability.nullable; + if (type.hasNonNull) return Nullability.nonNullable; + return Nullability.platform; + } + + @override + StabilityType visitArrayType(ArrayType node) { + return StabilityArrayType( + elementType: node.elementType.accept(_typeExporter), + nullability: nullabilityFromType(node), + ); + } + + @override + StabilityType visitPrimitiveType(PrimitiveType node) { + return StabilityPrimitiveType(name: node.name); + } + + @override + StabilityType visitDeclaredType(DeclaredType node) { + return StabilityDeclaredType( + binaryName: node.binaryName, + typeArguments: + node.params.map((param) => param.accept(_typeExporter)).toList(), + nullability: nullabilityFromType(node), + ); + } + + @override + StabilityType visitTypeVar(TypeVar node) { + return StabilityTypeVariable( + name: node.name, + nullability: nullabilityFromType(node), + ); + } + + @override + StabilityType visitWildcard(Wildcard node) { + return StabilityWildcard( + extendsBound: node.extendsBound?.accept(_typeExporter), + superBound: node.superBound?.accept(_typeExporter), + nullability: nullabilityFromType(node), + ); + } +} diff --git a/pkgs/jnigen/lib/src/bindings/graph_builder.dart b/pkgs/jnigen/lib/src/bindings/graph_builder.dart new file mode 100644 index 0000000000..d24398d6ac --- /dev/null +++ b/pkgs/jnigen/lib/src/bindings/graph_builder.dart @@ -0,0 +1,110 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:collection'; + +import 'package:path/path.dart' as p; + +import '../config/config.dart'; +import '../elements/elements.dart'; +import '../transformers/graph.dart' as graph; +import 'visitor.dart'; + +/// This creates the user-facing graph used for transformations like renaming, +/// excluding, and adding extra methods. +class GraphBuilder extends ElementVisitor + with TopLevelVisitor { + @override + final stage = GenerationStage.graphBuilder; + + final Config config; + + GraphBuilder(this.config); + + @override + graph.Bindings visit(Classes node) { + final classes = {}; + final visiting = {}; + final classNodeBuilder = _ClassNodeBuilder(classes, visiting); + for (final classDecl in node.decls.values) { + if (!classes.containsKey(classDecl.binaryName)) { + classDecl.accept(classNodeBuilder); + } + } + final files = LinkedHashMap( + equals: p.equals, hashCode: p.hash); + final fileNodeBuilder = _FileNodeBuilder(classes); + for (final MapEntry(key: path, value: file) in node.files.entries) { + files[path] = file.accept(fileNodeBuilder); + } + return graph.Bindings(node, classes, files); + } +} + +class _ClassNodeBuilder extends ElementVisitor { + final Map classes; + final Set visiting; + + _ClassNodeBuilder(this.classes, this.visiting); + + @override + void visit(ClassDecl node) { + // First visit the outer-class, the superclass, and the super-interfaces of + // this class to maintain topological ordering. + if (classes.containsKey(node.binaryName) || + visiting.contains(node.binaryName)) { + return; + } + visiting.add(node.binaryName); + node.outerClass?.accept(this); + if (node.superclass case final DeclaredType superType) { + if (!superType.classDecl.isImported) { + superType.classDecl.accept(this); + } + } + for (final interface in node.interfaces) { + if (interface case final DeclaredType superInterface) { + if (!superInterface.classDecl.isImported) { + superInterface.classDecl.accept(this); + } + } + } + final properties = Map.fromEntries(node.fields + .map((field) => MapEntry(field.name, graph.Property(field)))); + final methods = {}; + final methodNodeBuilder = _MethodNodeBuilder(); + for (final method in node.methods) { + methods[method.javaSig] = method.accept(methodNodeBuilder); + } + classes[node.binaryName] = graph.Class(node, properties, methods) + ..enclosingClass = node.outerClassBinaryName == null + ? null + : classes[node.outerClassBinaryName!]; + visiting.remove(node.binaryName); + } +} + +class _FileNodeBuilder extends ElementVisitor { + final Map allClasses; + + _FileNodeBuilder(this.allClasses); + + @override + graph.DartFile visit(DartFile node) { + final classes = {}; + for (final binaryName in node.classes.keys) { + classes[binaryName] = allClasses[binaryName]!; + } + return graph.DartFile(node, classes); + } +} + +class _MethodNodeBuilder extends ElementVisitor { + @override + graph.Method visit(Method node) { + final parameters = UnmodifiableListView( + node.params.map(graph.MethodParameter.new).toList()); + return graph.Method(node, parameters); + } +} diff --git a/pkgs/jnigen/lib/src/bindings/importer.dart b/pkgs/jnigen/lib/src/bindings/importer.dart new file mode 100644 index 0000000000..b894247368 --- /dev/null +++ b/pkgs/jnigen/lib/src/bindings/importer.dart @@ -0,0 +1,141 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; + +import 'package:pub_semver/pub_semver.dart'; +import 'package:yaml/yaml.dart'; + +import '../config/config_types.dart'; +import '../elements/elements.dart'; +import '../logging/logging.dart'; +import '../util/find_package.dart'; +import 'visitor.dart'; + +/// Modify this when symbols file format changes according to pub_semver. +final jsonVersion = Version(1, 0, 0); + +/// Imports the stability information from the previous runs of JNIgen from this +/// and other packages. +class Importer extends ElementVisitor> + with TopLevelVisitor { + @override + final stage = GenerationStage.importer; + + final Config config; + + Importer(this.config); + + @override + Future visit(Classes node) async { + for (final import in [ + // Implicitly importing package:jni symbols. + Uri.parse('package:jni/jni_symbols.yaml'), + ...?config.imports, + ]) { + // Getting the actual uri in case of package uris. + final Uri yamlUri; + final String importPath; + if (import.scheme == 'package') { + final packageName = import.pathSegments.first; + final packageRoot = await findPackageRoot(packageName); + if (packageRoot == null) { + log.fatal('package:$packageName was not found.'); + } + yamlUri = packageRoot + .resolve('lib/') + .resolve(import.pathSegments.sublist(1).join('/')); + importPath = 'package:$packageName'; + } else { + yamlUri = import; + importPath = ([...import.pathSegments]..removeLast()).join('/'); + } + log.finest('Parsing yaml file in url $yamlUri.'); + final YamlMap yaml; + try { + final symbolsFile = File.fromUri(yamlUri); + final content = symbolsFile.readAsStringSync(); + yaml = loadYaml(content, sourceUrl: yamlUri) as YamlMap; + } catch (e, s) { + log.warning(e); + log.warning(s); + log.fatal('Error while parsing yaml file "$import".'); + } + final version = Version.parse(yaml['version'] as String); + if (!VersionConstraint.compatibleWith(jsonVersion).allows(version)) { + log.fatal('"$import" is version "$version" which is not compatible with' + 'the current JNIgen symbols version $jsonVersion'); + } + final files = yaml['files'] as YamlMap; + for (final entry in files.entries) { + final filePath = entry.key as String; + final dartFile = DartFile('$importPath/$filePath', {}); + final classes = entry.value as YamlMap; + for (final classEntry in classes.entries) { + final binaryName = classEntry.key as String; + final decl = classEntry.value as YamlMap; + if (node.importedClasses.containsKey(binaryName)) { + log.fatal( + 'Re-importing "$binaryName" in "$import".\n' + 'Try hiding the class in import.', + ); + } + final classDecl = ClassDecl( + declKind: DeclKind.classKind, + binaryName: binaryName, + ) + ..isImported = true + ..file = dartFile + ..finalName = decl['name'] as String + ..superCount = decl['super_count'] as int + ..allTypeParams = [] + // TODO(https://github.com/dart-lang/native/issues/746): include + // outerClass in the interop information. + ..outerClass = null; + for (final typeParamEntry + in (decl['type_params'] as YamlMap?)?.entries ?? + >[]) { + final typeParamName = typeParamEntry.key as String; + final bounds = (typeParamEntry.value as YamlMap).entries.map((e) { + final boundName = e.key as String; + // Can only be DECLARED or TYPE_VARIABLE + if (!['DECLARED', 'TYPE_VARIABLE'].contains(e.value)) { + log.fatal( + 'Unsupported bound kind "${e.value}" for bound "$boundName" ' + 'in type parameter "$typeParamName" ' + 'of "$binaryName".', + ); + } + final ReferredType type; + if ((e.value as String) == 'DECLARED') { + type = DeclaredType(binaryName: boundName); + } else { + type = TypeVar(name: boundName); + } + return type; + }).toList(); + classDecl.allTypeParams.add( + TypeParam(name: typeParamName, bounds: bounds), + ); + } + node.importedClasses[binaryName] = classDecl; + } + } + + if (node.importedClasses.keys + .toSet() + .intersection(node.decls.keys.toSet()) + .isNotEmpty) { + log.fatal( + 'Trying to re-import the generated classes.\n' + 'Try hiding the class(es) in import.', + ); + } + + for (final className in node.importedClasses.keys) { + log.finest('Imported $className successfully.'); + } + } + } +} diff --git a/pkgs/jnigen/lib/src/bindings/kotlin_processor.dart b/pkgs/jnigen/lib/src/bindings/kotlin_processor.dart index 0b315de7ef..a23b92204a 100644 --- a/pkgs/jnigen/lib/src/bindings/kotlin_processor.dart +++ b/pkgs/jnigen/lib/src/bindings/kotlin_processor.dart @@ -30,9 +30,10 @@ String _toJavaBinaryName(String kotlinBinaryName) { binaryName; } -/// A [Visitor] that adds the the information from Kotlin's metadata to the Java -/// classes and methods. -class KotlinProcessor extends Visitor with TopLevelVisitor { +/// An [ElementVisitor] that adds the the information from Kotlin's metadata to +/// the Java classes and methods. +class KotlinProcessor extends ElementVisitor + with TopLevelVisitor { @override final GenerationStage stage = GenerationStage.kotlinProcessor; @@ -45,20 +46,21 @@ class KotlinProcessor extends Visitor with TopLevelVisitor { } } -class _KotlinClassProcessor extends Visitor { +class _KotlinClassProcessor extends ElementVisitor { @override void visit(ClassDecl node) { if (node.kotlinClass == null && node.kotlinPackage == null) { return; } // This [ClassDecl] is actually a Kotlin class. - if (node.kotlinClass != null) { - for (var i = 0; i < node.kotlinClass!.typeParameters.length; ++i) { - node.typeParams[i].accept( - _KotlinTypeParamProcessor(node.kotlinClass!.typeParameters[i])); + if (node.kotlinClass case final kotlinClass?) { + node.originalName = kotlinClass.name; + for (var i = 0; i < kotlinClass.typeParameters.length; ++i) { + node.typeParams[i] + .accept(_KotlinTypeParamProcessor(kotlinClass.typeParameters[i])); } if (node.superclass case final superClass?) { - final kotlinSuperTypes = node.kotlinClass!.superTypes.where( + final kotlinSuperTypes = kotlinClass.superTypes.where( (superType) => _toJavaBinaryName(superType.name ?? '') == superClass.name, ); @@ -131,13 +133,14 @@ void _processParams( } } -class _KotlinMethodProcessor extends Visitor { +class _KotlinMethodProcessor extends ElementVisitor { final KotlinFunction function; _KotlinMethodProcessor(this.function); @override void visit(Method node) { + node.originalName = function.name; _processParams(node.params, function.valueParameters); node.kotlinFunction = function; for (var i = 0; i < node.typeParams.length; ++i) { @@ -171,7 +174,7 @@ class _KotlinMethodProcessor extends Visitor { } } -class _KotlinConstructorProcessor extends Visitor { +class _KotlinConstructorProcessor extends ElementVisitor { final KotlinConstructor constructor; _KotlinConstructorProcessor(this.constructor); @@ -182,7 +185,7 @@ class _KotlinConstructorProcessor extends Visitor { } } -class _KotlinGetterProcessor extends Visitor { +class _KotlinGetterProcessor extends ElementVisitor { final KotlinProperty getter; _KotlinGetterProcessor(this.getter); @@ -193,7 +196,7 @@ class _KotlinGetterProcessor extends Visitor { } } -class _KotlinSetterProcessor extends Visitor { +class _KotlinSetterProcessor extends ElementVisitor { final KotlinProperty setter; _KotlinSetterProcessor(this.setter); @@ -207,29 +210,31 @@ class _KotlinSetterProcessor extends Visitor { } } -class _KotlinPropertyProcessor extends Visitor { +class _KotlinPropertyProcessor extends ElementVisitor { final KotlinProperty property; _KotlinPropertyProcessor(this.property); @override void visit(Field node) { + node.originalName = property.kotlinName; node.type.accept(_KotlinTypeProcessor(property.returnType)); } } -class _KotlinParamProcessor extends Visitor { +class _KotlinParamProcessor extends ElementVisitor { final KotlinValueParameter kotlinParam; _KotlinParamProcessor(this.kotlinParam); @override void visit(Param node) { + node.originalName = kotlinParam.name; node.type.accept(_KotlinTypeProcessor(kotlinParam.type)); } } -class _KotlinTypeParamProcessor extends Visitor { +class _KotlinTypeParamProcessor extends ElementVisitor { final KotlinTypeParameter kotlinTypeParam; _KotlinTypeParamProcessor(this.kotlinTypeParam); @@ -251,7 +256,7 @@ class _KotlinTypeParamProcessor extends Visitor { } } -class _KotlinTypeProcessor extends TypeVisitor { +class _KotlinTypeProcessor extends TypeVisitor with DefaultNonPrimitive { final KotlinType kotlinType; _KotlinTypeProcessor(this.kotlinType); diff --git a/pkgs/jnigen/lib/src/bindings/linker.dart b/pkgs/jnigen/lib/src/bindings/linker.dart index 512ee4607b..eda6fb1154 100644 --- a/pkgs/jnigen/lib/src/bindings/linker.dart +++ b/pkgs/jnigen/lib/src/bindings/linker.dart @@ -2,6 +2,8 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'dart:io'; + import '../config/config.dart'; import '../elements/elements.dart'; import '../logging/logging.dart'; @@ -9,14 +11,15 @@ import 'visitor.dart'; typedef _Resolver = ClassDecl Function(String? binaryName); -/// A [Visitor] that adds the correct [ClassDecl] references from the +/// An [ElementVisitor] that adds the correct [ClassDecl] references from the /// string binary names. /// /// It adds the following references: /// * Links [ClassDecl] objects from imported dependencies. /// * Adds references from child elements back to their parent elements. /// * Resolves Kotlin specific `asyncReturnType` for methods. -class Linker extends Visitor> with TopLevelVisitor { +class Linker extends ElementVisitor> + with TopLevelVisitor { @override final GenerationStage stage = GenerationStage.linker; @@ -32,8 +35,9 @@ class Linker extends Visitor> with TopLevelVisitor { OutputStructure.singleFile) { // Connect all to the root if the output is in single file mode. final path = root.toFilePath(); + final file = node.files[path] ??= DartFile(path, {...node.decls}); for (final decl in node.decls.values) { - decl.path = path; + decl.file = file; } } else { for (final decl in node.decls.values) { @@ -41,61 +45,52 @@ class Linker extends Visitor> with TopLevelVisitor { final className = dollarSign != -1 ? decl.binaryName.substring(0, dollarSign) : decl.binaryName; - final path = className.replaceAll('.', '/'); - decl.path = root.resolve(path).toFilePath(); + final path = root + .resolve( + '${className.replaceAll('.', Platform.pathSeparator)}.dart', + ) + .toFilePath(); + final file = node.files[path] ??= DartFile(path, {}); + decl.file = file; + file.classes[decl.binaryName] = decl; + // Create a `_package.dart` file in each package that exports all of the + // classes within that package. + final packagePath = root + .resolve(decl.packageName.replaceAll('.', Platform.pathSeparator)) + .resolve('_package.dart') + .toFilePath(); + final packageFile = node.files[packagePath] ??= DartFile( + packagePath, + {}, + ); + packageFile.exports.add(file); } } - // Find all the imported classes. - await config.importClasses(); - - if (config.importedClasses.keys - .toSet() - .intersection(node.decls.keys.toSet()) - .isNotEmpty) { - log.fatal( - 'Trying to re-import the generated classes.\n' - 'Try hiding the class(es) in import.', - ); - } - - for (final className in config.importedClasses.keys) { - log.finest('Imported $className successfully.'); - } - ClassDecl resolve(String? binaryName) { - return config.importedClasses[binaryName] ?? + return node.importedClasses[binaryName] ?? node.decls[binaryName] ?? resolve(DeclaredType.object.name); } DeclaredType.object.classDecl = resolve(DeclaredType.object.name); - final classLinker = _ClassLinker( - config, - resolve, - ); + final classLinker = _ClassLinker(config, resolve); for (final classDecl in node.decls.values) { classDecl.accept(classLinker); } } } -class _ClassLinker extends Visitor { +class _ClassLinker extends ElementVisitor { final Config config; final _Resolver resolve; final Set linked; - /// Keeps track of the [TypeParam]s that introduced each type variable. - final typeVarOrigin = {}; - - _ClassLinker( - this.config, - this.resolve, - ) : linked = {...config.importedClasses.values}; + _ClassLinker(this.config, this.resolve) : linked = {}; @override void visit(ClassDecl node) { - if (linked.contains(node)) return; + if (linked.contains(node) || node.isImported) return; log.finest('Linking ${node.binaryName}.'); linked.add(node); @@ -105,70 +100,108 @@ class _ClassLinker extends Visitor { node.outerClass?.accept(this); // Add type params of outer classes to the nested classes. - final allTypeParams = []; + node.allTypeParams = []; if (!node.isStatic) { - allTypeParams.addAll(node.outerClass?.allTypeParams ?? []); + node.allTypeParams.addAll( + node.outerClass?.allTypeParams.map( + (typeParam) => typeParam.clone(until: GenerationStage.linker), + ) ?? + [], + ); } - allTypeParams.addAll(node.typeParams); - node.allTypeParams = allTypeParams; + node.allTypeParams.addAll(node.typeParams); + + /// Keeps track of the [TypeParam]s that introduced each type variable. + final typeVarOrigin = {}; for (final typeParam in node.allTypeParams) { typeVarOrigin[typeParam.name] = typeParam; } + final typeLinker = _TypeLinker(resolve, typeVarOrigin); + for (final typeParam in node.typeParams) { + typeParam.accept(_TypeParamLinker(typeLinker)); + typeParam.parent = node; + } + node.superclass ??= DeclaredType.object; node.superclass!.accept(typeLinker); final superclass = (node.superclass! as DeclaredType).classDecl; superclass.accept(this); - final methodSignatures = {}; - final methodLinker = _MethodLinker(config, resolve, {...typeVarOrigin}); + final signatureToMethod = {}; for (final method in node.methods) { method.classDecl = node; - method.accept(methodLinker); - methodSignatures.add(method.javaSig); + method.accept(_MethodLinker(config, resolve, {...typeVarOrigin})); + signatureToMethod[method.javaSig] = method; } - // Add all methods from the superinterfaces of this class. + // Add all methods from the superinterfaces and the superclass. if (node.methods.isEmpty) { // Make the list modifiable. node.methods = []; } + + node.superCount = superclass.superCount + 1; + + final fieldLinker = _FieldLinker(typeLinker); + for (final field in node.fields) { + field.classDecl = node; + field.accept(fieldLinker); + } + final debug = node.binaryName == + 'com.github.dart_lang.jnigen.inheritance.DerivedInterface'; + if (debug) log.warning('signatures: $signatureToMethod'); + void moveMethod(Method method, DeclaredType fromType) { + if (signatureToMethod.containsKey(method.javaSig)) { + if (debug) + log.warning( + 'signatures contain ${method.javaSig} from ${method.classDecl.binaryName}'); + // If this method also exists in a super interface, the methods + // should share their sharedState. + final thisMethod = signatureToMethod[method.javaSig]!; + thisMethod.sharedState = method.sharedState; + } else { + if (debug) + log.warning( + 'signatures do not contain ${method.javaSig} from ${method.classDecl.binaryName}'); + final clonedMethod = method.clone(until: GenerationStage.linker); + clonedMethod.accept(_MethodMover(fromType: fromType, toClass: node)); + clonedMethod.accept(_MethodLinker(config, resolve, {...typeVarOrigin})); + signatureToMethod[clonedMethod.javaSig] = clonedMethod; + node.methods.add(clonedMethod); + } + } + for (final interface in node.interfaces) { interface.accept(typeLinker); if (interface case final DeclaredType interfaceType) { interfaceType.classDecl.accept(this); for (final interfaceMethod in interfaceType.classDecl.methods) { - final clonedMethod = - interfaceMethod.clone(until: GenerationStage.linker); - clonedMethod.accept(_MethodMover( - typeVarOrigin: {...typeVarOrigin}, - fromType: interfaceType, - toClass: node, - )); - if (!methodSignatures.contains(clonedMethod.javaSig)) { - clonedMethod.accept(methodLinker); - methodSignatures.add(clonedMethod.javaSig); - node.methods.add(clonedMethod); - } + moveMethod(interfaceMethod, interfaceType); } } } - node.superCount = superclass.superCount + 1; - - final fieldLinker = _FieldLinker(typeLinker); - for (final field in node.fields) { - field.classDecl = node; - field.accept(fieldLinker); + void moveField(Field field) { + // FIXME } - for (final typeParam in node.typeParams) { - typeParam.accept(_TypeParamLinker(typeLinker)); - typeParam.parent = node; + + if (node.superclass case final DeclaredType superType?) { + for (final method in superclass.methods) { + if (!method.isStatic && !method.isConstructor) { + moveMethod(method, superType); + } + } + for (final field in superclass.fields) { + if (!field.isStatic) { + moveField(field); + } + } } } } -class _MethodLinker extends Visitor { +class _MethodLinker extends ElementVisitor { _MethodLinker(this.config, this.resolve, this.typeVarOrigin) : typeLinker = _TypeLinker(resolve, typeVarOrigin); @@ -186,11 +219,12 @@ class _MethodLinker extends Visitor { final outerClassTypeParamCount = node.classDecl.allTypeParams.length - node.classDecl.typeParams.length; final outerClassTypeParams = [ - for (final typeParam - in node.classDecl.allTypeParams.take(outerClassTypeParamCount)) ...[ + for (final typeParam in node.classDecl.allTypeParams.take( + outerClassTypeParamCount, + )) ...[ TypeVar(name: typeParam.name) ..annotations = [if (typeParam.hasNonNull) Annotation.nonNull], - ] + ], ]; final outerClassType = DeclaredType( binaryName: node.classDecl.outerClass!.binaryName, @@ -218,6 +252,11 @@ class _MethodLinker extends Visitor { for (final typeParam in node.typeParams) { typeVarOrigin[typeParam.name] = typeParam; } + final typeParamLinker = _TypeParamLinker(typeLinker); + for (final typeParam in node.typeParams) { + typeParam.accept(typeParamLinker); + typeParam.parent = node; + } node.descriptor = node.accept(_MethodDescriptor(typeVarOrigin)); node.returnType.accept(typeLinker); @@ -231,12 +270,7 @@ class _MethodLinker extends Visitor { ...?node.annotations, ]; } - final typeParamLinker = _TypeParamLinker(typeLinker); final paramLinker = _ParamLinker(typeLinker); - for (final typeParam in node.typeParams) { - typeParam.accept(typeParamLinker); - typeParam.parent = node; - } for (final param in node.params) { param.accept(paramLinker); param.method = node; @@ -297,14 +331,9 @@ class _TypeLinker extends TypeVisitor { void visitPrimitiveType(PrimitiveType node) { // Do nothing. } - - @override - void visitNonPrimitiveType(ReferredType node) { - // Do nothing. - } } -class _FieldLinker extends Visitor { +class _FieldLinker extends ElementVisitor { _FieldLinker(this.typeLinker); final _TypeLinker typeLinker; @@ -316,18 +345,17 @@ class _FieldLinker extends Visitor { // `androidx.annotation.NonNull` only get applied to elements but not types. if (!node.type.hasNullabilityAnnotations && node.hasNullabilityAnnotations) { - node.type.annotations = [ - ...?node.type.annotations, - ...?node.annotations, - ]; + node.type.annotations = [...?node.type.annotations, ...?node.annotations]; } node.type.accept(typeLinker); - node.type.descriptor = - node.type.accept(_TypeDescriptor(typeLinker.typeVarOrigin)); + node.descriptor ??= node.type.descriptor; + node.type.descriptor = node.type.accept( + _TypeDescriptor(typeLinker.typeVarOrigin), + ); } } -class _TypeParamLinker extends Visitor { +class _TypeParamLinker extends ElementVisitor { _TypeParamLinker(this.typeLinker); final _TypeLinker typeLinker; @@ -340,7 +368,7 @@ class _TypeParamLinker extends Visitor { } } -class _ParamLinker extends Visitor { +class _ParamLinker extends ElementVisitor { _ParamLinker(this.typeLinker); final _TypeLinker typeLinker; @@ -352,10 +380,7 @@ class _ParamLinker extends Visitor { // `androidx.annotation.NonNull` only get applied to elements but not types. if (!node.type.hasNullabilityAnnotations && node.hasNullabilityAnnotations) { - node.type.annotations = [ - ...?node.type.annotations, - ...?node.annotations, - ]; + node.type.annotations = [...?node.type.annotations, ...?node.annotations]; } node.type.accept(typeLinker); } @@ -364,19 +389,16 @@ class _ParamLinker extends Visitor { /// Once a [Method] is cloned and added to another [ClassDecl], the original /// type parameters can be replaced with other ones and its `classDecl` will be /// different. This visitor fixes these issues after the cloning is done. -class _MethodMover extends Visitor { - final Map typeVarOrigin; +class _MethodMover extends ElementVisitor { final DeclaredType fromType; final ClassDecl toClass; - _MethodMover({ - required this.typeVarOrigin, - required this.fromType, - required this.toClass, - }); + _MethodMover({required this.fromType, required this.toClass}); @override void visit(Method node) { + final b = node.javaSig == 'push(Ljava/lang/Object;)V'; + if (b) log.warning('moving ${node.javaSig}...'); node.classDecl = toClass; final typeMover = _TypeMover(fromType: fromType); if (node.returnType is TypeVar) { @@ -386,7 +408,10 @@ class _MethodMover extends Visitor { } for (final param in node.params) { if (param.type is TypeVar) { + if (b) log.warning('param ${param.name} is a type var'); + if (b) log.warning('origin: ${(param.type as TypeVar).origin.parent}'); param.type = typeMover.replaceTypeVar(param.type as TypeVar); + if (b) log.warning('now it became: ${param.type.name}'); } else { param.type.accept(typeMover); } @@ -400,15 +425,10 @@ class _MethodMover extends Visitor { } } } - // Since the types can be changed, the descriptor can be changed as well. - for (final typeParam in node.typeParams) { - typeVarOrigin[typeParam.name] = typeParam; - } - node.descriptor = node.accept(_MethodDescriptor(typeVarOrigin)); } } -class _TypeMover extends TypeVisitor { +class _TypeMover extends TypeVisitor with DefaultNonPrimitive { final DeclaredType fromType; _TypeMover({required this.fromType}); @@ -420,8 +440,9 @@ class _TypeMover extends TypeVisitor { ReferredType replaceTypeVar(TypeVar typeVar) { if (typeVar.origin.parent == fromType.classDecl) { - final index = fromType.classDecl.allTypeParams - .indexWhere((typeParam) => typeParam.name == typeVar.name); + final index = fromType.classDecl.allTypeParams.indexWhere( + (typeParam) => typeParam.name == typeVar.name, + ); if (index != -1) { if (index >= fromType.params.length) { return DeclaredType.object.clone(); @@ -462,7 +483,7 @@ class _TypeMover extends TypeVisitor { /// /// https://docs.oracle.com/en/java/javase/18/docs/specs/jni/types.html#type-signatures /// Also see: [_TypeDescriptor] -class _MethodDescriptor extends Visitor { +class _MethodDescriptor extends ElementVisitor { final Map typeVarOrigin; _MethodDescriptor(this.typeVarOrigin); @@ -478,8 +499,9 @@ class _MethodDescriptor extends Visitor { s.write(desc); } s.write(')'); - final returnTypeDesc = - node.returnType.accept(_TypeDescriptor(typeVarOrigin)); + final returnTypeDesc = node.returnType.accept( + _TypeDescriptor(typeVarOrigin), + ); node.returnType.descriptor = returnTypeDesc; s.write(returnTypeDesc); return s.toString(); @@ -489,7 +511,7 @@ class _MethodDescriptor extends Visitor { /// JVM representation of type signatures. /// /// https://docs.oracle.com/en/java/javase/18/docs/specs/jni/types.html#type-signatures -class _TypeDescriptor extends TypeVisitor { +class _TypeDescriptor extends TypeVisitor with DefaultNonPrimitive { final Map typeVarOrigin; _TypeDescriptor(this.typeVarOrigin); diff --git a/pkgs/jnigen/lib/src/bindings/printer.dart b/pkgs/jnigen/lib/src/bindings/printer.dart index 392ce95744..f5c53bc4d2 100644 --- a/pkgs/jnigen/lib/src/bindings/printer.dart +++ b/pkgs/jnigen/lib/src/bindings/printer.dart @@ -1,7 +1,7 @@ import '../elements/elements.dart'; import 'visitor.dart'; -class Printer extends Visitor { +class Printer extends ElementVisitor { const Printer(); @override void visit(Classes node) { @@ -13,7 +13,7 @@ class Printer extends Visitor { } } -class _ClassPrinter extends Visitor { +class _ClassPrinter extends ElementVisitor { const _ClassPrinter(); @override void visit(ClassDecl node) { @@ -31,7 +31,7 @@ class _ClassPrinter extends Visitor { } } -class _MethodPrinter extends Visitor { +class _MethodPrinter extends ElementVisitor { const _MethodPrinter(); @override void visit(Method node) { @@ -48,7 +48,7 @@ class _MethodPrinter extends Visitor { } } -class _FieldPrinter extends Visitor { +class _FieldPrinter extends ElementVisitor { const _FieldPrinter(); @override void visit(Field node) { @@ -58,7 +58,7 @@ class _FieldPrinter extends Visitor { } } -class _ParamPrinter extends Visitor { +class _ParamPrinter extends ElementVisitor { const _ParamPrinter(); @override @@ -132,12 +132,9 @@ class _TypePrinter extends TypeVisitor { printAnnotation(node); print('${' ' * depth}'); } - - @override - void visitNonPrimitiveType(ReferredType node) {} } -class _AnnotationPrinter extends Visitor { +class _AnnotationPrinter extends ElementVisitor { int depth; _AnnotationPrinter(this.depth); diff --git a/pkgs/jnigen/lib/src/bindings/renamer.dart b/pkgs/jnigen/lib/src/bindings/renamer.dart deleted file mode 100644 index c1a8d854c9..0000000000 --- a/pkgs/jnigen/lib/src/bindings/renamer.dart +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import '../config/config.dart'; -import '../elements/elements.dart'; -import '../logging/logging.dart'; -import 'visitor.dart'; - -class _Allowed { - static const none = 0; - static const fields = 1 << 0; - static const methods = 1 << 1; - static const classes = 1 << 2; - static const all = fields | methods | classes; -} - -enum _ElementKind { - field, - method, - klass; - - bool isAllowed(String identifier) { - return 1 << index & (_keywords[identifier] ?? _Allowed.all) != 0; - } -} - -const _keywords = { - 'abstract': _Allowed.fields | _Allowed.methods, - 'assert': _Allowed.none, - 'await': _Allowed.none, // Cannot be used in async context - 'break': _Allowed.none, - 'case': _Allowed.none, - 'catch': _Allowed.none, - 'class': _Allowed.none, - 'const': _Allowed.none, - 'continue': _Allowed.none, - 'covariant': _Allowed.fields | _Allowed.methods, - 'default': _Allowed.none, - 'deferred': _Allowed.fields | _Allowed.methods, - 'do': _Allowed.none, - 'dynamic': _Allowed.fields | _Allowed.methods, - 'else': _Allowed.none, - 'enum': _Allowed.none, - 'export': _Allowed.fields | _Allowed.methods, - 'extends': _Allowed.none, - 'extension': _Allowed.fields | _Allowed.methods, - 'external': _Allowed.fields | _Allowed.methods, - 'factory': _Allowed.fields | _Allowed.methods, - 'false': _Allowed.none, - 'final': _Allowed.none, - 'finally': _Allowed.none, - 'for': _Allowed.none, - 'Function': _Allowed.fields | _Allowed.methods, - 'if': _Allowed.none, - 'implements': _Allowed.fields | _Allowed.methods, - 'import': _Allowed.methods, - 'in': _Allowed.none, - 'interface': _Allowed.fields | _Allowed.methods, - 'is': _Allowed.none, - 'late': _Allowed.fields | _Allowed.methods, - 'library': _Allowed.fields | _Allowed.methods, - 'mixin': _Allowed.fields | _Allowed.methods, - 'new': _Allowed.none, - 'null': _Allowed.none, - 'operator': _Allowed.fields | _Allowed.methods, - 'part': _Allowed.fields | _Allowed.methods, - 'required': _Allowed.fields | _Allowed.methods, - 'rethrow': _Allowed.none, - 'return': _Allowed.none, - 'static': _Allowed.fields | _Allowed.methods, - 'super': _Allowed.none, - 'switch': _Allowed.none, - 'this': _Allowed.none, - 'throw': _Allowed.none, - 'true': _Allowed.none, - 'try': _Allowed.none, - 'typedef': _Allowed.fields | _Allowed.methods, - 'var': _Allowed.none, - 'void': _Allowed.none, - 'while': _Allowed.none, - 'with': _Allowed.none, - 'yield': _Allowed.none, // Cannot be used in async context -}; - -/// Methods & properties already defined by dart JObject base class. -/// -/// If a second method or field has the same name, it will be appended by a -/// numeric suffix. -const Map _definedSyms = { - 'as': 1, - 'fromReference': 1, - 'toString': 1, - 'hashCode': 1, - 'runtimeType': 1, - 'noSuchMethod': 1, - 'reference': 1, - 'isA': 1, - 'isInstanceOf': 1, - 'isReleased': 1, - 'isNull': 1, - 'use': 1, - 'release': 1, - 'releasedBy': 1, - 'jClass': 1, - 'type': 1, -}; - -String _preprocess(String name) { - // Replaces the `_` prefix with `$_` to prevent hiding public members in Dart. - // For example `_foo` -> `$_foo`. - String makePublic(String name) => - name.startsWith('_') ? '\$_${name.substring(1)}' : name; - - // Replaces each dollar sign with two dollar signs in [name]. - // For example `$foo$$bar$` -> `$$foo$$$$bar$$`. - String doubleDollarSigns(String name) => name.replaceAll(r'$', r'$$'); - - return makePublic(doubleDollarSigns(name)); -} - -/// Appends `$` to [name] if [name] is a Dart keyword. -/// -/// Examples: -/// * `yield` -> `yield$` -/// * `foo` -> `foo` -String _keywordRename(String name, _ElementKind kind) => - kind.isAllowed(name) ? name : '$name\$'; - -String _renameConflict( - Map counts, String name, _ElementKind kind) { - if (counts.containsKey(name)) { - final count = counts[name]!; - final renamed = '$name\$$count'; - counts[name] = count + 1; - return renamed; - } - counts[name] = 1; - return _keywordRename(name, kind); -} - -class Renamer extends Visitor with TopLevelVisitor { - @override - final GenerationStage stage = GenerationStage.renamer; - - final Config config; - - Renamer(this.config); - - @override - void visit(Classes node) { - final classRenamer = _ClassRenamer(config); - - for (final classDecl in node.decls.values) { - classDecl.accept(classRenamer); - } - } -} - -class _ClassRenamer implements Visitor { - final Config config; - final Set renamed; - final Map topLevelNameCounts = {}; - final Map> nameCounts = {}; - - _ClassRenamer( - this.config, - ) : renamed = {...config.importedClasses.values}; - - @override - void visit(ClassDecl node) { - if (renamed.contains(node)) return; - log.finest('Renaming ${node.binaryName}.'); - renamed.add(node); - - nameCounts[node] = {..._definedSyms}; - if (node.declKind == DeclKind.interfaceKind) { - nameCounts[node]!['implement'] = 1; - nameCounts[node]!['implementIn'] = 1; - } - node.methodNumsAfterRenaming = {}; - - final superClass = (node.superclass! as DeclaredType).classDecl; - superClass.accept(this); - nameCounts[node]!.addAll(nameCounts[superClass] ?? {}); - - if (node.outerClass case final outerClass?) { - outerClass.accept(this); - } - - final outerClassName = - node.outerClass == null ? '' : '${node.outerClass!.finalName}\$'; - final className = - '$outerClassName${_preprocess(node.userDefinedName ?? node.name)}'; - - // When generating all the classes in a single file - // the names need to be unique. - final uniquifyName = - config.outputConfig.dartConfig.structure == OutputStructure.singleFile; - node.finalName = uniquifyName - ? _renameConflict(topLevelNameCounts, className, _ElementKind.klass) - : className; - - if (node.userDefinedName == null || - node.userDefinedName == node.finalName) { - log.fine('Class ${node.binaryName} is named ${node.finalName}'); - } else { - log.warning('Renaming Class ${node.binaryName} to ${node.userDefinedName}' - ' causes a name collision. Renamed to ${node.finalName} instead.'); - } - - // Rename fields before renaming methods. In case a method and a field have - // identical names, the field will keep its original name and the - // method will be renamed. - final fieldRenamer = _FieldRenamer( - config, - uniquifyName && node.isTopLevel ? topLevelNameCounts : nameCounts[node]!, - ); - for (final field in node.fields) { - field.accept(fieldRenamer); - } - - final methodRenamer = _MethodRenamer( - config, - uniquifyName && node.isTopLevel ? topLevelNameCounts : nameCounts[node]!, - ); - for (final method in node.methods) { - method.accept(methodRenamer); - } - } -} - -class _MethodRenamer implements Visitor { - _MethodRenamer(this.config, this.nameCounts); - - final Config config; - final Map nameCounts; - - @override - void visit(Method node) { - final name = _preprocess( - node.userDefinedName ?? (node.isConstructor ? 'new' : node.name)); - final sig = node.javaSig; - // If node is in super class, assign its number, overriding it. - final superClass = (node.classDecl.superclass! as DeclaredType).classDecl; - final superNum = superClass.methodNumsAfterRenaming[sig]; - if (superNum != null) { - // Don't rename if superNum == 0 - // Unless the node name is a keyword. - final superNumText = superNum == 0 ? '' : '$superNum'; - final methodName = - superNum == 0 ? _keywordRename(name, _ElementKind.method) : name; - node.finalName = '$methodName$superNumText'; - node.classDecl.methodNumsAfterRenaming[sig] = superNum; - } else { - node.finalName = _renameConflict(nameCounts, name, _ElementKind.method); - node.classDecl.methodNumsAfterRenaming[sig] = nameCounts[name]! - 1; - } - - if (node.userDefinedName == null || - node.userDefinedName == node.finalName) { - log.fine('Method ${node.classDecl.binaryName}#${node.name}' - ' is named ${node.finalName}'); - } else { - log.warning('Renaming Method ${node.classDecl.binaryName}#' - '${node.name} to ${node.userDefinedName} cause a name collision. ' - 'Renamed to ${node.finalName} instead.'); - } - - final paramRenamer = _ParamRenamer(config); - for (final param in node.params) { - param.accept(paramRenamer); - } - } -} - -class _FieldRenamer implements Visitor { - _FieldRenamer(this.config, this.nameCounts); - - final Config config; - final Map nameCounts; - - @override - void visit(Field node) { - final fieldName = _preprocess(node.userDefinedName ?? node.name); - node.finalName = _renameConflict(nameCounts, fieldName, _ElementKind.field); - - if (node.userDefinedName == null || - node.userDefinedName == node.finalName) { - log.fine('Field ${node.classDecl.binaryName}#${node.name}' - ' is named ${node.finalName}'); - } else { - log.warning('Renaming Field ${node.classDecl.binaryName}#${node.name}' - ' to ${node.userDefinedName} cause a name collision. ' - 'Renamed to ${node.finalName} instead.'); - } - } -} - -class _ParamRenamer implements Visitor { - _ParamRenamer(this.config); - - final Config config; - - @override - void visit(Param node) { - node.finalName = - _keywordRename(node.userDefinedName ?? node.name, _ElementKind.field); - } -} diff --git a/pkgs/jnigen/lib/src/bindings/resolver.dart b/pkgs/jnigen/lib/src/bindings/resolver.dart deleted file mode 100644 index 25ba34ded5..0000000000 --- a/pkgs/jnigen/lib/src/bindings/resolver.dart +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:math'; - -import '../elements/elements.dart'; -import '../logging/logging.dart'; - -class Resolver { - /// Class corresponding to currently writing file. - /// - /// Is `null` when in single file mode. - final String? currentClass; - - /// Explicit import mappings. - final Map importedClasses; - - /// Names of all classes in input. - final Set inputClassNames; - - final List _importStrings = []; - - final Set _relativeImportedClasses = {}; - final Map _importedNameToClass = { - r'_$core': '', - r'_$jni': '', - }; - final Map _classToImportedName = {}; - - Resolver({ - required this.importedClasses, - required this.currentClass, - this.inputClassNames = const {}, - }); - - static String getFileClassName(String binaryName) { - final dollarSign = binaryName.indexOf('\$'); - if (dollarSign != -1) { - return binaryName.substring(0, dollarSign); - } - return binaryName; - } - - /// splits [str] into 2 from last occurence of [sep] - static List cutFromLast(String str, String sep) { - final li = str.lastIndexOf(sep); - if (li == -1) { - return ['', str]; - } - return [str.substring(0, li), str.substring(li + 1)]; - } - - /// Get the prefix for the class - String resolvePrefix(ClassDecl classDecl) { - if (classDecl.path == 'package:jni/jni.dart') { - return r'jni$_.'; - } - final binaryName = classDecl.binaryName; - final target = getFileClassName(binaryName); - - // For classes we generate (inside [inputClassNames]) no import - // (and therefore no prefix) is necessary when: - // * Never necessary in single file mode - // * In multi file mode if the target is the same as the current class - if ((currentClass == null || target == currentClass) && - inputClassNames.contains(binaryName)) { - return ''; - } - - if (_classToImportedName.containsKey(target)) { - // This package was already resolved - // but we still need to check if it was a relative import, in which case - // the class not in inputClassNames cannot be mapped here. - if (!_relativeImportedClasses.contains(target) || - inputClassNames.contains(binaryName)) { - final importedName = _classToImportedName[target]; - return '$importedName.'; - } - } - - final classImport = getImport(target, binaryName); - log.finest('$target resolved to $classImport for $binaryName'); - if (classImport == null) { - return ''; - } - - final pkgName = cutFromLast(target, '.')[1].toLowerCase(); - - // We always name imports with an underscore suffix, so that they can be - // never shadowed by a parameter or local variable. - var importedName = '$pkgName\$_'; - var suffix = 0; - while (_importedNameToClass.containsKey(importedName)) { - ++suffix; - importedName = '$pkgName\$_$suffix'; - } - - _importedNameToClass[importedName] = target; - _classToImportedName[target] = importedName; - _importStrings.add("import '$classImport' as $importedName;\n"); - return '$importedName.'; - } - - /// Returns import string for [classToResolve], or `null` if the class is not - /// found. - /// - /// [binaryName] is the class name trying to be resolved. This parameter is - /// requested so that classes included in current bindings can be resolved - /// using relative path. - String? getImport(String classToResolve, String binaryName) { - final prefix = classToResolve; - - // short circuit if the requested class is specified directly in import map. - if (importedClasses.containsKey(binaryName)) { - return importedClasses[binaryName]!.path; - } - - if (prefix.isEmpty) { - throw UnsupportedError('unexpected: empty package name.'); - } - - final dest = classToResolve.split('.'); - final src = currentClass!.split('.'); - // Use relative import when the required class is included in current set - // of bindings. - if (inputClassNames.contains(binaryName)) { - var common = 0; - // find the common prefix path directory of current package, and directory - // of target package - // src.length - 1 simply corresponds to directory of the package. - for (var i = 0; i < src.length - 1 && i < dest.length - 1; i++) { - if (src[i] == dest[i]) { - common++; - } else { - break; - } - } - final pathToCommon = '../' * ((src.length - 1) - common); - final pathToClass = dest.sublist(max(common, 0)).join('/'); - _relativeImportedClasses.add(classToResolve); - return '$pathToCommon$pathToClass.dart'; - } - - return null; - } - - List get importStrings { - return _importStrings..sort(); - } -} diff --git a/pkgs/jnigen/lib/src/bindings/visitor.dart b/pkgs/jnigen/lib/src/bindings/visitor.dart index 7e360d4a5a..b800156369 100644 --- a/pkgs/jnigen/lib/src/bindings/visitor.dart +++ b/pkgs/jnigen/lib/src/bindings/visitor.dart @@ -4,30 +4,41 @@ import '../elements/elements.dart'; -abstract class Visitor, R> { - const Visitor(); +abstract class ElementVisitor, R> { + const ElementVisitor(); R visit(T node); } -mixin TopLevelVisitor on Visitor { +mixin TopLevelVisitor on ElementVisitor { GenerationStage get stage; } abstract class TypeVisitor { const TypeVisitor(); - R visitNonPrimitiveType(ReferredType node); R visitPrimitiveType(PrimitiveType node); + R visitArrayType(ArrayType node); + R visitDeclaredType(DeclaredType node); + R visitTypeVar(TypeVar node); + R visitWildcard(Wildcard node); +} + +mixin DefaultNonPrimitive on TypeVisitor { + R visitNonPrimitiveType(ReferredType node); + @override R visitArrayType(ArrayType node) => visitNonPrimitiveType(node); + @override R visitDeclaredType(DeclaredType node) => visitNonPrimitiveType(node); + @override R visitTypeVar(TypeVar node) => visitNonPrimitiveType(node); + @override R visitWildcard(Wildcard node) => visitNonPrimitiveType(node); } extension MultiVisitor> on Iterable> { /// Accepts all lazily. Remember to call `.toList()` or similar methods! - Iterable accept(Visitor v) { + Iterable accept(ElementVisitor v) { return map((e) => e.accept(v)); } } diff --git a/pkgs/jnigen/lib/src/config/config_types.dart b/pkgs/jnigen/lib/src/config/config_types.dart index c4ee00280a..738b40814e 100644 --- a/pkgs/jnigen/lib/src/config/config_types.dart +++ b/pkgs/jnigen/lib/src/config/config_types.dart @@ -6,20 +6,13 @@ import 'dart:io'; import 'package:logging/logging.dart'; import 'package:path/path.dart' as p; -import 'package:pub_semver/pub_semver.dart'; -import 'package:yaml/yaml.dart'; -import '../elements/elements.dart'; -import '../elements/j_elements.dart' as j_ast; import '../logging/logging.dart'; -import '../util/find_package.dart'; +import '../transformers/graph.dart' show Visitor; import 'config_exception.dart'; import 'experiments.dart'; import 'yaml_reader.dart'; -/// Modify this when symbols file format changes according to pub_semver. -final _currentVersion = Version(1, 0, 0); - /// Configuration for dependencies to be downloaded using maven. /// /// Dependency names should be listed in groupId:artifactId:version format. @@ -217,8 +210,8 @@ class SymbolsOutputConfig { final Uri path; SymbolsOutputConfig(this.path) { - if (p.extension(path.toFilePath()) != '.yaml') { - throw ConfigException('Symbol\'s output path must end with ".yaml".'); + if (p.extension(path.toFilePath()) != '.json') { + throw ConfigException('Symbol\'s output path must end with ".json".'); } } } @@ -258,23 +251,24 @@ void _validateClassName(String className) { /// Configuration for jnigen binding generation. class Config { - Config( - {required this.outputConfig, - required this.classes, - this.experiments, - this.sourcePath, - this.classPath, - this.preamble, - this.customClassBody, - this.androidSdkConfig, - this.mavenDownloads, - this.summarizerOptions, - this.nonNullAnnotations, - this.nullableAnnotations, - this.logLevel = Level.INFO, - this.dumpJsonTo, - this.imports, - this.visitors}) { + Config({ + required this.outputConfig, + required this.classes, + this.experiments, + this.sourcePath, + this.classPath, + this.preamble, + this.customClassBody, + this.androidSdkConfig, + this.mavenDownloads, + this.summarizerOptions, + this.nonNullAnnotations, + this.nullableAnnotations, + this.logLevel = Level.INFO, + this.dumpJsonTo, + this.imports, + this.visitors, + }) { for (final className in classes) { _validateClassName(className); } @@ -323,9 +317,6 @@ class Config { /// List of dependencies. final List? imports; - /// Call [importClasses] before using this. - late final Map importedClasses; - /// Annotations specifying that this type is nullable. final List? nullableAnnotations; @@ -338,106 +329,8 @@ class Config { /// Used for testing package:jnigen. final Map? customClassBody; - // User custom visitors. - List? visitors; - - Future importClasses() async { - importedClasses = {}; - for (final import in [ - // Implicitly importing package:jni symbols. - Uri.parse('package:jni/jni_symbols.yaml'), - ...?imports, - ]) { - // Getting the actual uri in case of package uris. - final Uri yamlUri; - final String importPath; - if (import.scheme == 'package') { - final packageName = import.pathSegments.first; - final packageRoot = await findPackageRoot(packageName); - if (packageRoot == null) { - log.fatal('package:$packageName was not found.'); - } - yamlUri = packageRoot - .resolve('lib/') - .resolve(import.pathSegments.sublist(1).join('/')); - importPath = 'package:$packageName'; - } else { - yamlUri = import; - importPath = ([...import.pathSegments]..removeLast()).join('/'); - } - log.finest('Parsing yaml file in url $yamlUri.'); - final YamlMap yaml; - try { - final symbolsFile = File.fromUri(yamlUri); - final content = symbolsFile.readAsStringSync(); - yaml = loadYaml(content, sourceUrl: yamlUri) as YamlMap; - } catch (e, s) { - log.warning(e); - log.warning(s); - log.fatal('Error while parsing yaml file "$import".'); - } - final version = Version.parse(yaml['version'] as String); - if (!VersionConstraint.compatibleWith(_currentVersion).allows(version)) { - log.fatal('"$import" is version "$version" which is not compatible with' - 'the current JNIgen symbols version $_currentVersion'); - } - final files = yaml['files'] as YamlMap; - for (final entry in files.entries) { - final filePath = entry.key as String; - final classes = entry.value as YamlMap; - for (final classEntry in classes.entries) { - final binaryName = classEntry.key as String; - final decl = classEntry.value as YamlMap; - if (importedClasses.containsKey(binaryName)) { - log.fatal( - 'Re-importing "$binaryName" in "$import".\n' - 'Try hiding the class in import.', - ); - } - final classDecl = ClassDecl( - declKind: DeclKind.classKind, - binaryName: binaryName, - ) - ..path = '$importPath/$filePath' - ..finalName = decl['name'] as String - ..superCount = decl['super_count'] as int - ..allTypeParams = [] - // TODO(https://github.com/dart-lang/native/issues/746): include - // outerClass in the interop information. - ..outerClass = null; - for (final typeParamEntry - in (decl['type_params'] as YamlMap?)?.entries ?? - >[]) { - final typeParamName = typeParamEntry.key as String; - final bounds = (typeParamEntry.value as YamlMap).entries.map((e) { - final boundName = e.key as String; - // Can only be DECLARED or TYPE_VARIABLE - if (!['DECLARED', 'TYPE_VARIABLE'].contains(e.value)) { - log.fatal( - 'Unsupported bound kind "${e.value}" for bound "$boundName" ' - 'in type parameter "$typeParamName" ' - 'of "$binaryName".', - ); - } - final ReferredType type; - if ((e.value as String) == 'DECLARED') { - type = DeclaredType(binaryName: boundName); - } else { - type = TypeVar(name: boundName); - } - return type; - }).toList(); - classDecl.allTypeParams.add( - TypeParam(name: typeParamName, bounds: bounds), - ); - } - classDecl.methodNumsAfterRenaming = - (decl['methods'] as YamlMap?)?.cast() ?? {}; - importedClasses[binaryName] = classDecl; - } - } - } - } + /// User-provided visitors used to transform the generated bindings. + List? visitors; /// Directory containing the YAML configuration file, if any. Uri? get configRoot => _configRoot; diff --git a/pkgs/jnigen/lib/src/elements/elements.dart b/pkgs/jnigen/lib/src/elements/elements.dart index 268d2d04ce..479bfbe291 100644 --- a/pkgs/jnigen/lib/src/elements/elements.dart +++ b/pkgs/jnigen/lib/src/elements/elements.dart @@ -2,14 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'dart:collection'; + import 'package:json_annotation/json_annotation.dart'; import 'package:meta/meta.dart'; +import 'package:path/path.dart' as p; -// Types to describe java API elements - -import '../bindings/kotlin_processor.dart'; -import '../bindings/linker.dart'; -import '../bindings/renamer.dart'; import '../bindings/visitor.dart'; part 'elements.g.dart'; @@ -19,11 +17,12 @@ enum GenerationStage { // The order of the enum elements must match the order in // `../generate_bindings.dart`. unprocessed, - userVisitors, - excluder, + importer, kotlinProcessor, linker, - renamer, + graphBuilder, + userTransformers, + exporter, dartGenerator; bool operator <=(GenerationStage stage) { @@ -31,10 +30,118 @@ enum GenerationStage { } } -abstract class Element> { - const Element(); +base mixin Element> { + R accept(ElementVisitor v); +} + +base mixin Annotated { + abstract List? annotations; + + static final nullableAnnotations = [ + // Taken from https://kotlinlang.org/docs/java-interop.html#nullability-annotations + 'org.jetbrains.annotations.Nullable', + 'org.jspecify.nullness.Nullable', + 'com.android.annotations.Nullable', + 'androidx.annotation.Nullable', + 'android.support.annotations.Nullable', + 'edu.umd.cs.findbugs.annotations.Nullable', + 'org.eclipse.jdt.annotation.Nullable', + 'lombok.Nullable', + 'io.reactivex.rxjava3.annotations.Nullable', + ]; + bool get hasNullable { + return annotations?.any( + (annotation) => + nullableAnnotations.contains(annotation.binaryName) || + annotation.binaryName == 'javax.annotation.Nullable' && + annotation.properties['when'] == 'ALWAYS', + ) ?? + false; + } + + static final nonNullAnnotations = [ + // Taken from https://kotlinlang.org/docs/java-interop.html#nullability-annotations + 'org.jetbrains.annotations.NotNull', + 'org.jspecify.nullness.NonNull', + 'com.android.annotations.NonNull', + 'androidx.annotation.NonNull', + 'android.support.annotations.NonNull', + 'edu.umd.cs.findbugs.annotations.NonNull', + 'org.eclipse.jdt.annotation.NonNull', + 'lombok.NonNull', + 'io.reactivex.rxjava3.annotations.NonNull', + ]; + bool get hasNonNull { + return annotations?.any( + (annotation) => + nonNullAnnotations.contains(annotation.binaryName) || + annotation.binaryName == 'javax.annotation.Nonnull' && + annotation.properties['when'] == 'ALWAYS', + ) ?? + false; + } + + bool get hasNullabilityAnnotations => hasNonNull || hasNullable; + + bool get isNullable { + if (hasNullable) { + return true; + } + return !hasNonNull; + } +} + +base mixin HasModifiers> on Element { + Set get modifiers; + + bool get isAbstract => modifiers.contains('abstract'); + bool get isStatic => modifiers.contains('static'); + bool get isFinal => modifiers.contains('final'); + bool get isPublic => modifiers.contains('public'); + bool get isProtected => modifiers.contains('protected'); + bool get isSynthetic => modifiers.contains('synthetic'); + bool get isBridge => modifiers.contains('bridge'); +} + +base mixin Importable> on Element { + /// Whether this class has been imported from a different JNIgen-generated + /// package. + /// + /// Can be modified in [GenerationStage.importer]. + @JsonKey(includeFromJson: false) + bool isImported = false; +} + +/// Represents an element that could potentially be renamed. +base mixin Renamable> on Element { + /// The name used in JVM bytecode or Java source. + /// + /// Might be different to [originalName] for Kotlin code. + @JsonKey(includeFromJson: false) + String get name; + + /// Defaults to [name] but will be changed to the original Kotlin name of the + /// element in [GenerationStage.kotlinProcessor] if it has originated from + /// Kotlin. + @JsonKey(includeFromJson: false) + late String originalName = name; + + /// The name loaded from the API stability file. + /// + /// Populated in [GenerationStage.importer]. + @JsonKey(includeFromJson: false) + // FIXME + late final String? stableName = null; + + /// The name used in the generated bindings. + @JsonKey(includeFromJson: false) + String? finalName; +} - R accept(Visitor v); +base mixin Excludable> on Element { + /// Whether this element is excluded from the generated bindings. + @JsonKey(includeFromJson: false) + bool isExcluded = false; } /// A kind describes the type of a declaration. @@ -48,11 +155,18 @@ enum DeclKind { enumKind, } -class Classes implements Element { - const Classes(this.decls); +final class Classes with Element { + Classes(this.decls); final Map decls; + /// Populated in [GenerationStage.importer]. + final Map importedClasses = {}; + + /// Populated in [GenerationStage.linker]. + final Map files = + HashMap(equals: p.equals, hashCode: p.hash); + factory Classes.fromJson(List json) { final decls = {}; for (final declJson in json) { @@ -63,7 +177,20 @@ class Classes implements Element { } @override - R accept(Visitor v) { + R accept(ElementVisitor v) { + return v.visit(this); + } +} + +final class DartFile with Element, Importable { + final String path; + final Map classes; + final List exports = []; + + DartFile(this.path, this.classes); + + @override + R accept(ElementVisitor v) { return v.visit(this); } } @@ -73,9 +200,15 @@ class Classes implements Element { // option in java. @JsonSerializable(createToJson: false) -class ClassDecl with ClassMember, Annotated implements Element { +final class ClassDecl + with + Element, + HasModifiers, + Annotated, + Renamable, + Excludable, + Importable { ClassDecl({ - this.isExcluded = false, this.annotations, this.javadoc, required this.declKind, @@ -92,12 +225,6 @@ class ClassDecl with ClassMember, Annotated implements Element { this.kotlinPackage, }); - @JsonKey(includeFromJson: false) - bool isExcluded; - - @JsonKey(includeFromJson: false) - String? userDefinedName; - @override final Set modifiers; @@ -108,19 +235,25 @@ class ClassDecl with ClassMember, Annotated implements Element { final JavaDocComment? javadoc; final DeclKind declKind; final String binaryName; + + /// The type parameters introduced by this exact class. + /// + /// Does not contain the type parameters of any outer-classes if this class + /// is a non-static inner-class. For a list of all type parameters including + /// the ones from the outer-classes, use [allTypeParams]. List typeParams; List methods; List fields; final List interfaces; - /// Will default to java.lang.Object if null by [Linker]. + /// Will default to java.lang.Object if null in [GenerationStage.linker]. ReferredType? superclass; final String? outerClassBinaryName; /// Outer class's [ClassDecl] obtained from [outerClassBinaryName]. /// - /// Populated by [Linker]. + /// Populated in [GenerationStage.linker]. @JsonKey(includeFromJson: false) late ClassDecl? outerClass; @@ -134,16 +267,17 @@ class ClassDecl with ClassMember, Annotated implements Element { /// The number of super classes this type has. /// - /// Populated by [Linker]. + /// Populated in [GenerationStage.linker]. @JsonKey(includeFromJson: false) late int superCount; - /// Final name of this class. + /// Classes can have custom added fields and methods. This is used to ensure + /// the identifiers of these extra members do not collide with the other + /// identifiers present in the class. /// - /// Populated by [Renamer]. + /// Populated in [GenerationStage.importer]. @JsonKey(includeFromJson: false) - @override - late String finalName; + final Set extraMembers = {}; /// Name of the type class. @JsonKey(includeFromJson: false) @@ -156,23 +290,17 @@ class ClassDecl with ClassMember, Annotated implements Element { /// /// For `Foo.Bar.Baz` it is [T, U, V, W]. /// - /// Populated by [Linker]. + /// Populated in [GenerationStage.linker]. @JsonKey(includeFromJson: false) late List allTypeParams; - /// The path which this class is generated in. - /// - /// Populated by [Linker]. - @JsonKey(includeFromJson: false) - late String path; - - /// The numeric suffix of the methods. + /// The file which this class is generated in. /// - /// Populated by [Renamer]. + /// Populated in [GenerationStage.linker]. @JsonKey(includeFromJson: false) - late Map methodNumsAfterRenaming; + late DartFile file; - /// Populated by [Linker]. + /// Populated in [GenerationStage.linker]. @JsonKey(includeFromJson: false) final Map operators = {}; @@ -183,7 +311,7 @@ class ClassDecl with ClassMember, Annotated implements Element { /// /// Used for overloading comparison operators. /// - /// Populated by [Linker]. + /// Populated in [GenerationStage.linker]. @JsonKey(includeFromJson: false) Method? compareTo; @@ -198,13 +326,10 @@ class ClassDecl with ClassMember, Annotated implements Element { _$ClassDeclFromJson(json); @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } - @override - ClassDecl get classDecl => this; - /// Simple name of this class without the outerclasses. /// /// This is not uniquely identifiable from the [binaryName]. For instance, @@ -222,8 +347,19 @@ class ClassDecl with ClassMember, Annotated implements Element { @JsonKey(includeFromJson: false) bool get isNested => outerClassBinaryName != null; - /// Whether the class is actually only a number of top-level Kotlin Functions. - bool get isTopLevel => kotlinPackage != null; + /// Whether the class is actually only a number of top-level Kotlin Functions + /// and properties. + @JsonKey(includeFromJson: false) + late bool isTopLevel = kotlinPackage != null; +} + +@JsonEnum(fieldRename: FieldRename.screamingSnake, alwaysCreate: true) +enum TypeKind { + primitive, + typeVariable, + wildcard, + declared, + array, } sealed class ReferredType with Annotated { @@ -231,7 +367,7 @@ sealed class ReferredType with Annotated { String get name; - /// Populated by [Linker]. + /// Populated in [GenerationStage.linker]. @JsonKey(includeFromJson: false) String? descriptor; @@ -239,29 +375,28 @@ sealed class ReferredType with Annotated { // we have to temporarily store `type` in a JSON map, and switch on the // enum value received. factory ReferredType.fromJson(Map json) { - final kind = json['kind'] as String; + final kind = $enumDecode(_$TypeKindEnumMap, json['kind']); final typeJson = json['type'] as Map; switch (kind) { - case 'PRIMITIVE': + case TypeKind.primitive: return PrimitiveType.fromJson(typeJson); - case 'TYPE_VARIABLE': + case TypeKind.typeVariable: return TypeVar.fromJson(typeJson); - case 'WILDCARD': + case TypeKind.wildcard: return Wildcard.fromJson(typeJson); - case 'DECLARED': + case TypeKind.declared: return DeclaredType.fromJson(typeJson); - case 'ARRAY': + case TypeKind.array: return ArrayType.fromJson(typeJson); } - throw UnsupportedError('The referred type of kind $kind is not supported'); } R accept(TypeVisitor v); - ReferredType clone({GenerationStage until = GenerationStage.userVisitors}); + ReferredType clone({GenerationStage until = GenerationStage.unprocessed}); } -class PrimitiveType extends ReferredType { +final class PrimitiveType extends ReferredType { static final _primitives = { 'byte': PrimitiveType._( name: 'byte', @@ -371,7 +506,7 @@ class PrimitiveType extends ReferredType { } @override - PrimitiveType clone({GenerationStage until = GenerationStage.userVisitors}) { + PrimitiveType clone({GenerationStage until = GenerationStage.unprocessed}) { final cloned = PrimitiveType._( boxedName: boxedName, cType: cType, @@ -388,7 +523,7 @@ class PrimitiveType extends ReferredType { } @JsonSerializable(createToJson: false) -class DeclaredType extends ReferredType { +final class DeclaredType extends ReferredType { static final object = DeclaredType(binaryName: 'java.lang.Object'); DeclaredType({ @@ -428,7 +563,7 @@ class DeclaredType extends ReferredType { params.any((param) => param.hasNullabilityAnnotations); @override - DeclaredType clone({GenerationStage until = GenerationStage.userVisitors}) { + DeclaredType clone({GenerationStage until = GenerationStage.unprocessed}) { final cloned = DeclaredType( binaryName: binaryName, annotations: [...?annotations], @@ -442,8 +577,8 @@ class DeclaredType extends ReferredType { } @JsonSerializable(createToJson: false) -class TypeVar extends ReferredType { - /// Populated by [Linker]. +final class TypeVar extends ReferredType { + /// Populated in [GenerationStage.linker]. @JsonKey(includeFromJson: false) late TypeParam origin; @@ -498,7 +633,7 @@ class TypeVar extends ReferredType { } @override - TypeVar clone({GenerationStage until = GenerationStage.userVisitors}) { + TypeVar clone({GenerationStage until = GenerationStage.unprocessed}) { final cloned = TypeVar(name: name, annotations: [...?annotations]); if (GenerationStage.linker <= until) { cloned.origin = origin; @@ -509,7 +644,7 @@ class TypeVar extends ReferredType { } @JsonSerializable(createToJson: false) -class Wildcard extends ReferredType { +final class Wildcard extends ReferredType { Wildcard({this.extendsBound, this.superBound, this.annotations}); ReferredType? extendsBound; ReferredType? superBound; @@ -552,7 +687,7 @@ class Wildcard extends ReferredType { (extendsBound?.hasNullabilityAnnotations ?? false); @override - Wildcard clone({GenerationStage until = GenerationStage.userVisitors}) { + Wildcard clone({GenerationStage until = GenerationStage.unprocessed}) { final cloned = Wildcard( annotations: [...?annotations], extendsBound: extendsBound?.clone(until: until), @@ -566,7 +701,7 @@ class Wildcard extends ReferredType { } @JsonSerializable(createToJson: false) -class ArrayType extends ReferredType { +final class ArrayType extends ReferredType { ArrayType({required this.elementType, this.annotations}); ReferredType elementType; @@ -592,7 +727,7 @@ class ArrayType extends ReferredType { super.hasNullabilityAnnotations || elementType.hasNullabilityAnnotations; @override - ArrayType clone({GenerationStage until = GenerationStage.userVisitors}) { + ArrayType clone({GenerationStage until = GenerationStage.unprocessed}) { final cloned = ArrayType( elementType: elementType.clone(until: until), annotations: [...?annotations], @@ -604,82 +739,25 @@ class ArrayType extends ReferredType { } } -mixin Annotated { - abstract List? annotations; +/// This class represents the shared state of all [Method]s of the same name and +/// signature within a class hierarchy. +final class SharedMethodState { + String? finalName; + bool isExcluded = false; - static final nullableAnnotations = [ - // Taken from https://kotlinlang.org/docs/java-interop.html#nullability-annotations - 'org.jetbrains.annotations.Nullable', - 'org.jspecify.nullness.Nullable', - 'com.android.annotations.Nullable', - 'androidx.annotation.Nullable', - 'android.support.annotations.Nullable', - 'edu.umd.cs.findbugs.annotations.Nullable', - 'org.eclipse.jdt.annotation.Nullable', - 'lombok.Nullable', - 'io.reactivex.rxjava3.annotations.Nullable', - ]; - bool get hasNullable { - return annotations?.any( - (annotation) => - nullableAnnotations.contains(annotation.binaryName) || - annotation.binaryName == 'javax.annotation.Nullable' && - annotation.properties['when'] == 'ALWAYS', - ) ?? - false; - } - - static final nonNullAnnotations = [ - // Taken from https://kotlinlang.org/docs/java-interop.html#nullability-annotations - 'org.jetbrains.annotations.NotNull', - 'org.jspecify.nullness.NonNull', - 'com.android.annotations.NonNull', - 'androidx.annotation.NonNull', - 'android.support.annotations.NonNull', - 'edu.umd.cs.findbugs.annotations.NonNull', - 'org.eclipse.jdt.annotation.NonNull', - 'lombok.NonNull', - 'io.reactivex.rxjava3.annotations.NonNull', - ]; - bool get hasNonNull { - return annotations?.any( - (annotation) => - nonNullAnnotations.contains(annotation.binaryName) || - annotation.binaryName == 'javax.annotation.Nonnull' && - annotation.properties['when'] == 'ALWAYS', - ) ?? - false; - } - - bool get hasNullabilityAnnotations => hasNonNull || hasNullable; - - bool get isNullable { - if (hasNullable) { - return true; - } - return !hasNonNull; - } -} - -mixin ClassMember { - String get name; - ClassDecl get classDecl; - Set get modifiers; - String get finalName; - - bool get isAbstract => modifiers.contains('abstract'); - bool get isStatic => modifiers.contains('static'); - bool get isFinal => modifiers.contains('final'); - bool get isPublic => modifiers.contains('public'); - bool get isProtected => modifiers.contains('protected'); - bool get isSynthetic => modifiers.contains('synthetic'); - bool get isBridge => modifiers.contains('bridge'); + SharedMethodState(); } @JsonSerializable(createToJson: false) -class Method with ClassMember, Annotated implements Element { +final class Method + with + Element, + HasModifiers, + Annotated, + Renamable, + Excludable, + Importable { Method({ - this.userDefinedIsExcluded = false, this.annotations, this.javadoc, this.modifiers = const {}, @@ -690,8 +768,11 @@ class Method with ClassMember, Annotated implements Element { required this.returnType, }); + /// The original name in the bytecode or Java source. Might be different to + /// [originalName] for Kotlin methods. @override final String name; + @override final Set modifiers; @override @@ -701,56 +782,66 @@ class Method with ClassMember, Annotated implements Element { List params; ReferredType returnType; - /// Populated by user-defined visitors. - @JsonKey(includeFromJson: false) - bool userDefinedIsExcluded; - - /// Populated by user-defined visitors. - @JsonKey(includeFromJson: false) - String? userDefinedName; - - /// Populated by [KotlinProcessor]. + /// Populated in [GenerationStage.kotlinProcessor]. @JsonKey(includeFromJson: false) KotlinFunction? kotlinFunction; /// The actual return type when the method is a Kotlin's suspend fun. /// - /// Populated by [KotlinProcessor]. + /// Populated in [GenerationStage.kotlinProcessor]. @JsonKey(includeFromJson: false) ReferredType? asyncReturnType; /// The [ClassDecl] where this method is defined. /// - /// Populated by [Linker]. + /// Populated in [GenerationStage.linker]. @JsonKey(includeFromJson: false) - @override late ClassDecl classDecl; + /// Populated in [GenerationStage.linker]. + @JsonKey(includeFromJson: false) + late SharedMethodState sharedState = SharedMethodState(); + + @JsonKey(includeFromJson: false) + @override + // ignore: overridden_fields + late String originalName = name == '' ? 'new' : name; + + @override + String? get finalName => sharedState.finalName; + + @override + set finalName(String? finalName) { + sharedState.finalName = finalName; + } + + @override + bool get isExcluded => sharedState.isExcluded; + + @override + set isExcluded(bool isExcluded) { + sharedState.isExcluded = isExcluded; + } + /// Can be used to match with [KotlinFunction]'s descriptor. /// /// Can create a unique signature in combination with [name]. - /// Populated either by the ASM backend or [Linker]. + /// Populated either by the ASM backend or in [GenerationStage.linker]. String? descriptor; @JsonKey(includeFromJson: false) late String javaSig = '$name$descriptor'; - /// Populated by [Renamer]. - @JsonKey(includeFromJson: false) - @override - late String finalName; - bool get isConstructor => name == ''; factory Method.fromJson(Map json) => _$MethodFromJson(json); - Method clone({GenerationStage until = GenerationStage.userVisitors}) { + Method clone({GenerationStage until = GenerationStage.unprocessed}) { final cloned = Method( name: name, returnType: returnType.clone(until: until), annotations: [...?annotations], descriptor: descriptor, - userDefinedIsExcluded: userDefinedIsExcluded, javadoc: javadoc, modifiers: {...modifiers}, params: params.map((param) => param.clone(until: until)).toList(), @@ -762,10 +853,13 @@ class Method with ClassMember, Annotated implements Element { // properties of the previous steps. switch (until) { case GenerationStage.dartGenerator: - case GenerationStage.renamer: + case GenerationStage.exporter: + case GenerationStage.userTransformers: + cloned.isExcluded = isExcluded; cloned.finalName = finalName; - continue linker; - linker: + continue graphBuilder; + graphBuilder: + case GenerationStage.graphBuilder: case GenerationStage.linker: cloned.descriptor = descriptor; cloned.classDecl = classDecl; @@ -775,30 +869,28 @@ class Method with ClassMember, Annotated implements Element { for (final typeParam in cloned.typeParams) { typeParam.parent = cloned; } + cloned.sharedState = sharedState; continue kotlinProcessor; kotlinProcessor: case GenerationStage.kotlinProcessor: cloned.kotlinFunction = kotlinFunction; cloned.asyncReturnType = asyncReturnType; - continue excluder; - excluder: - case GenerationStage.excluder: - case GenerationStage.userVisitors: - cloned.userDefinedIsExcluded = userDefinedIsExcluded; - cloned.userDefinedName = userDefinedName; + continue importer; + importer: + case GenerationStage.importer: case GenerationStage.unprocessed: } return cloned; } @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } } @JsonSerializable(createToJson: false) -class Param with Annotated implements Element { +final class Param with Element, Annotated, Renamable, Importable { Param({ this.annotations, this.javadoc, @@ -806,9 +898,6 @@ class Param with Annotated implements Element { required this.type, }); - @JsonKey(includeFromJson: false) - String? userDefinedName; - @override List? annotations; final JavaDocComment? javadoc; @@ -817,22 +906,19 @@ class Param with Annotated implements Element { bool get isNullable => type.isNullable || super.hasNullable; // Synthetic methods might not have parameter names. + @override @JsonKey(defaultValue: 'synthetic') final String name; ReferredType type; - /// Populated by [Linker]. + /// Populated in [GenerationStage.linker]. @JsonKey(includeFromJson: false) late Method method; - /// Populated by [Renamer]. - @JsonKey(includeFromJson: false) - late String finalName; - factory Param.fromJson(Map json) => _$ParamFromJson(json); - Param clone({GenerationStage until = GenerationStage.userVisitors}) { + Param clone({GenerationStage until = GenerationStage.unprocessed}) { final cloned = Param( name: name, type: type, @@ -842,36 +928,46 @@ class Param with Annotated implements Element { if (GenerationStage.linker <= until) { cloned.method = method; } - if (GenerationStage.renamer <= until) { + if (GenerationStage.userTransformers <= until) { cloned.finalName = finalName; } return cloned; } @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } } +/// This class represents the shared state of all [Field]s of the same name and +/// type within a class hierarchy. +final class SharedFieldState { + String? finalName; + bool isExcluded = false; + + SharedFieldState(); +} + @JsonSerializable(createToJson: false) -class Field with ClassMember, Annotated implements Element { +final class Field + with + Element, + HasModifiers, + Annotated, + Renamable, + Excludable, + Importable { Field({ - this.isExcluded = false, this.annotations, this.javadoc, this.modifiers = const {}, required this.name, required this.type, + required this.descriptor, this.defaultValue, }); - @JsonKey(includeFromJson: false) - bool isExcluded; - - @JsonKey(includeFromJson: false) - String? userDefinedName; - @override final String name; @override @@ -883,28 +979,40 @@ class Field with ClassMember, Annotated implements Element { final ReferredType type; final Object? defaultValue; + /// Can be used to match with [KotlinFunction]'s descriptor. + /// + /// Can create a unique signature in combination with [name]. + /// Populated either by the ASM backend or in [GenerationStage.linker]. + String? descriptor; + /// The [ClassDecl] where this field is defined. /// - /// Populated by [Linker]. + /// Populated in [GenerationStage.linker]. @JsonKey(includeFromJson: false) - @override late ClassDecl classDecl; - /// Populated by [Renamer]. + /// Populated in [GenerationStage.linker]. @JsonKey(includeFromJson: false) + late SharedFieldState sharedState = SharedFieldState(); + @override - late String finalName; + String? get finalName => sharedState.finalName; + + @override + set finalName(String? finalName) { + sharedState.finalName = finalName; + } factory Field.fromJson(Map json) => _$FieldFromJson(json); @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } } @JsonSerializable(createToJson: false) -class TypeParam with Annotated implements Element { +final class TypeParam with Element, Annotated { TypeParam({required this.name, this.bounds = const [], this.annotations}); final String name; @@ -920,15 +1028,15 @@ class TypeParam with Annotated implements Element { /// Can either be a [ClassDecl] or a [Method]. /// - /// Populated by [Linker]. + /// Populated in [GenerationStage.linker]. @JsonKey(includeFromJson: false) - late ClassMember parent; + late HasModifiers parent; factory TypeParam.fromJson(Map json) => _$TypeParamFromJson(json); /// Set [parent] after cloning. - TypeParam clone({GenerationStage until = GenerationStage.userVisitors}) { + TypeParam clone({GenerationStage until = GenerationStage.unprocessed}) { final cloned = TypeParam( name: name, annotations: [...?annotations], @@ -941,13 +1049,13 @@ class TypeParam with Annotated implements Element { } @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } } @JsonSerializable(createToJson: false) -class JavaDocComment implements Element { +final class JavaDocComment with Element { JavaDocComment({this.comment = ''}); final String comment; @@ -956,7 +1064,7 @@ class JavaDocComment implements Element { _$JavaDocCommentFromJson(json); @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } } @@ -998,7 +1106,7 @@ List typePathFromString(String? string) { return typePaths; } -sealed class TypePathStep { +final class TypePathStep { const TypePathStep(); } @@ -1044,7 +1152,7 @@ final class ToTypeParam extends TypePathStep { } @JsonSerializable(createToJson: false) -class Annotation implements Element { +final class Annotation with Element { /// Specifies that this type can be null. static const Annotation nullable = // Any other valid `Nullable` annotation would work. @@ -1071,13 +1179,13 @@ class Annotation implements Element { _$AnnotationFromJson(json); @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } } @JsonSerializable(createToJson: false) -class KotlinClass implements Element { +final class KotlinClass with Element { KotlinClass({ required this.name, required this.moduleName, @@ -1118,13 +1226,13 @@ class KotlinClass implements Element { _$KotlinClassFromJson(json); @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } } @JsonSerializable(createToJson: false) -class KotlinPackage implements Element { +final class KotlinPackage with Element { KotlinPackage({this.functions = const [], this.properties = const []}); final List functions; @@ -1134,13 +1242,13 @@ class KotlinPackage implements Element { _$KotlinPackageFromJson(json); @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } } @JsonSerializable(createToJson: false) -class KotlinFunction { +final class KotlinFunction { KotlinFunction({ required this.name, required this.descriptor, @@ -1184,7 +1292,7 @@ class KotlinFunction { } @JsonSerializable(createToJson: false) -class KotlinConstructor implements Element { +final class KotlinConstructor with Element { KotlinConstructor({ required this.name, required this.descriptor, @@ -1201,13 +1309,13 @@ class KotlinConstructor implements Element { _$KotlinConstructorFromJson(json); @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } } @JsonSerializable(createToJson: false) -class KotlinProperty implements Element { +final class KotlinProperty with Element { KotlinProperty({ this.fieldName, this.fieldDescriptor, @@ -1255,13 +1363,13 @@ class KotlinProperty implements Element { _$KotlinPropertyFromJson(json); @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } } @JsonSerializable(createToJson: false) -class KotlinType implements Element { +final class KotlinType with Element { KotlinType({ required this.flags, required this.kind, @@ -1282,7 +1390,7 @@ class KotlinType implements Element { _$KotlinTypeFromJson(json); @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } @@ -1311,7 +1419,7 @@ enum KmVariance { } @JsonSerializable(createToJson: false) -class KotlinTypeParameter implements Element { +final class KotlinTypeParameter with Element { KotlinTypeParameter({ required this.name, required this.id, @@ -1330,13 +1438,13 @@ class KotlinTypeParameter implements Element { _$KotlinTypeParameterFromJson(json); @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } } @JsonSerializable(createToJson: false) -class KotlinValueParameter implements Element { +final class KotlinValueParameter with Element { KotlinValueParameter({ required this.name, required this.flags, @@ -1353,12 +1461,12 @@ class KotlinValueParameter implements Element { _$KotlinValueParameterFromJson(json); @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } } -sealed class KotlinTypeArgument implements Element { +sealed class KotlinTypeArgument with Element { KotlinTypeArgument(); factory KotlinTypeArgument.fromJson(Map json) => @@ -1370,14 +1478,14 @@ sealed class KotlinTypeArgument implements Element { ); @override - R accept(Visitor v) { + R accept(ElementVisitor v) { return v.visit(this); } } -class KotlinWildcard extends KotlinTypeArgument {} +final class KotlinWildcard extends KotlinTypeArgument {} -class KotlinTypeProjection extends KotlinTypeArgument { +final class KotlinTypeProjection extends KotlinTypeArgument { KotlinTypeProjection({required this.type, required this.variance}); final KotlinType type; diff --git a/pkgs/jnigen/lib/src/elements/elements.g.dart b/pkgs/jnigen/lib/src/elements/elements.g.dart index 57ec0cc35a..b252101379 100644 --- a/pkgs/jnigen/lib/src/elements/elements.g.dart +++ b/pkgs/jnigen/lib/src/elements/elements.g.dart @@ -143,6 +143,7 @@ Field _$FieldFromJson(Map json) => Field( const {}, name: json['name'] as String, type: ReferredType.fromJson(json['type'] as Map), + descriptor: json['descriptor'] as String?, defaultValue: json['defaultValue'], ); @@ -359,3 +360,11 @@ KotlinValueParameter _$KotlinValueParameterFromJson( : KotlinType.fromJson( json['varargElementType'] as Map), ); + +const _$TypeKindEnumMap = { + TypeKind.primitive: 'PRIMITIVE', + TypeKind.typeVariable: 'TYPE_VARIABLE', + TypeKind.wildcard: 'WILDCARD', + TypeKind.declared: 'DECLARED', + TypeKind.array: 'ARRAY', +}; diff --git a/pkgs/jnigen/lib/src/elements/j_elements.dart b/pkgs/jnigen/lib/src/elements/j_elements.dart deleted file mode 100644 index 50fe889f27..0000000000 --- a/pkgs/jnigen/lib/src/elements/j_elements.dart +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'elements.dart' as ast; - -abstract class Element { - void accept(Visitor visitor); -} - -abstract class Visitor { - void visitClass(ClassDecl c) {} - void visitMethod(Method method) {} - void visitField(Field field) {} - void visitParam(Param parameter) {} -} - -class Classes implements Element { - Classes(this._classes); - final ast.Classes _classes; - - @override - void accept(Visitor visitor) { - for (final value in _classes.decls.values) { - final classDecl = ClassDecl(value); - classDecl.accept(visitor); - } - } - - void let(void Function(dynamic userClasses) param0) {} -} - -class ClassDecl implements Element { - ClassDecl(this._classDecl); - final ast.ClassDecl _classDecl; - - String get binaryName => _classDecl.binaryName; - - bool get isExcluded => _classDecl.isExcluded; - set isExcluded(bool value) => _classDecl.isExcluded = value; - - String get name => _classDecl.userDefinedName ?? _classDecl.name; - set name(String newName) => _classDecl.userDefinedName = newName; - - String get originalName => _classDecl.name; - - @override - void accept(Visitor visitor) { - visitor.visitClass(this); - if (_classDecl.isExcluded) return; - for (final method in _classDecl.methods) { - Method(method).accept(visitor); - } - for (var field in _classDecl.fields) { - Field(field).accept(visitor); - } - } -} - -class Method implements Element { - Method(this._method); - - final ast.Method _method; - - bool get isExcluded => _method.userDefinedIsExcluded; - set isExcluded(bool value) => _method.userDefinedIsExcluded = value; - - String get name => _method.userDefinedName ?? _method.name; - set name(String newName) => _method.userDefinedName = newName; - - String get originalName => _method.name; - - bool get isConstructor => _method.isConstructor; - - @override - void accept(Visitor visitor) { - visitor.visitMethod(this); - if (_method.userDefinedIsExcluded) return; - for (final param in _method.params) { - Param(param).accept(visitor); - } - } -} - -class Param implements Element { - Param(this._param); - - final ast.Param _param; - - String get name => _param.userDefinedName ?? _param.name; - set name(String newName) => _param.userDefinedName = newName; - - String get originalName => _param.name; - - @override - void accept(Visitor visitor) { - visitor.visitParam(this); - } -} - -class Field implements Element { - Field(this._field); - - final ast.Field _field; - - bool get isExcluded => _field.isExcluded; - set isExcluded(bool value) => _field.isExcluded = value; - - String get name => _field.userDefinedName ?? _field.name; - set name(String newName) => _field.userDefinedName = newName; - - String get originalName => _field.name; - - @override - void accept(Visitor visitor) { - visitor.visitField(this); - } -} diff --git a/pkgs/jnigen/lib/src/elements/stability_models.dart b/pkgs/jnigen/lib/src/elements/stability_models.dart new file mode 100644 index 0000000000..bd42bda202 --- /dev/null +++ b/pkgs/jnigen/lib/src/elements/stability_models.dart @@ -0,0 +1,266 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:json_annotation/json_annotation.dart'; +import 'package:pub_semver/pub_semver.dart'; + +part 'stability_models.g.dart'; + +String _versionToString(Version v) => v.toString(); + +@JsonSerializable() +final class StabilityInfo { + @JsonKey(fromJson: Version.parse, toJson: _versionToString) + final Version formatVersion; + final String packageName; + final Map files; + + StabilityInfo({ + required this.formatVersion, + required this.packageName, + required this.files, + }); + + factory StabilityInfo.fromJson(Map json) => + _$StabilityInfoFromJson(json); + + Map toJson() => _$StabilityInfoToJson(this); +} + +@JsonSerializable() +final class StabilityFile { + final Map classes; + + StabilityFile({required this.classes}); + + factory StabilityFile.fromJson(Map json) => + _$StabilityFileFromJson(json); + + Map toJson() => _$StabilityFileToJson(this); +} + +@JsonSerializable() +final class StabilityClass { + final String name; + final StabilityType superClass; + final List superInterfaces; + final Map fields; + final Map methods; + final List typeParameters; + + StabilityClass({ + required this.name, + required this.superClass, + required this.superInterfaces, + required this.fields, + required this.methods, + required this.typeParameters, + }); + + factory StabilityClass.fromJson(Map json) => + _$StabilityClassFromJson(json); + + Map toJson() => _$StabilityClassToJson(this); +} + +@JsonSerializable() +final class StabilityField { + final String name; + final StabilityType type; + + StabilityField({required this.name, required this.type}); + + factory StabilityField.fromJson(Map json) => + _$StabilityFieldFromJson(json); + + Map toJson() => _$StabilityFieldToJson(this); +} + +@JsonSerializable() +final class StabilityMethod { + final String name; + final List typeParameters; + final List methodParameters; + final StabilityType returnType; + + StabilityMethod({ + required this.name, + required this.typeParameters, + required this.methodParameters, + required this.returnType, + }); + + factory StabilityMethod.fromJson(Map json) => + _$StabilityMethodFromJson(json); + + Map toJson() => _$StabilityMethodToJson(this); +} + +@JsonSerializable() +final class StabilityMethodParameter { + final String name; + final StabilityType type; + + StabilityMethodParameter({required this.name, required this.type}); + + factory StabilityMethodParameter.fromJson(Map json) => + _$StabilityMethodParameterFromJson(json); + + Map toJson() => _$StabilityMethodParameterToJson(this); +} + +@JsonSerializable() +final class StabilityTypeParameter { + final String name; + final List bounds; + + StabilityTypeParameter({required this.name, required this.bounds}); + + factory StabilityTypeParameter.fromJson(Map json) => + _$StabilityTypeParameterFromJson(json); + + Map toJson() => _$StabilityTypeParameterToJson(this); +} + +@JsonEnum(alwaysCreate: true) +enum StabilityTypeKind { + primitive, + typeVariable, + wildcard, + declared, + array, +} + +@JsonEnum(alwaysCreate: true) +enum Nullability { + /// The type is explicitly non-nullable. + nonNullable, + + /// The type is explicitly nullable. + nullable, + + /// The nullability is unspecified. + platform, +} + +sealed class StabilityType { + // Since json_serializable doesn't directly support union types, + // we have to temporarily store `type` in a JSON map, and switch on the + // enum value received. + factory StabilityType.fromJson(Map json) { + final kind = $enumDecode(_$StabilityTypeKindEnumMap, json['kind']); + final typeJson = json['type'] as Map; + switch (kind) { + case StabilityTypeKind.primitive: + return StabilityPrimitiveType.fromJson(typeJson); + case StabilityTypeKind.typeVariable: + return StabilityTypeVariable.fromJson(typeJson); + case StabilityTypeKind.wildcard: + return StabilityWildcard.fromJson(typeJson); + case StabilityTypeKind.declared: + return StabilityDeclaredType.fromJson(typeJson); + case StabilityTypeKind.array: + return StabilityArrayType.fromJson(typeJson); + } + } + + Map toJson(); +} + +@JsonSerializable() +final class StabilityPrimitiveType implements StabilityType { + final String name; + + StabilityPrimitiveType({required this.name}); + + factory StabilityPrimitiveType.fromJson(Map json) => + _$StabilityPrimitiveTypeFromJson(json); + + @override + Map toJson() => { + 'kind': _$StabilityTypeKindEnumMap[StabilityTypeKind.primitive], + 'type': _$StabilityPrimitiveTypeToJson(this) + }; +} + +@JsonSerializable() +final class StabilityTypeVariable implements StabilityType { + final String name; + final Nullability nullability; + + StabilityTypeVariable({required this.name, required this.nullability}); + + factory StabilityTypeVariable.fromJson(Map json) => + _$StabilityTypeVariableFromJson(json); + + @override + Map toJson() => { + 'kind': _$StabilityTypeKindEnumMap[StabilityTypeKind.typeVariable], + 'type': _$StabilityTypeVariableToJson(this) + }; +} + +@JsonSerializable() +final class StabilityWildcard implements StabilityType { + final StabilityType? extendsBound; + final StabilityType? superBound; + final Nullability nullability; + + StabilityWildcard({ + this.extendsBound, + this.superBound, + required this.nullability, + }); + + factory StabilityWildcard.fromJson(Map json) => + _$StabilityWildcardFromJson(json); + + @override + Map toJson() => { + 'kind': _$StabilityTypeKindEnumMap[StabilityTypeKind.wildcard], + 'type': _$StabilityWildcardToJson(this) + }; +} + +@JsonSerializable() +final class StabilityDeclaredType implements StabilityType { + final String binaryName; + final List typeArguments; + final Nullability nullability; + + StabilityDeclaredType({ + required this.binaryName, + required this.typeArguments, + required this.nullability, + }); + + factory StabilityDeclaredType.fromJson(Map json) => + _$StabilityDeclaredTypeFromJson(json); + + @override + Map toJson() => { + 'kind': _$StabilityTypeKindEnumMap[StabilityTypeKind.declared], + 'type': _$StabilityDeclaredTypeToJson(this) + }; +} + +@JsonSerializable() +final class StabilityArrayType implements StabilityType { + final StabilityType elementType; + final Nullability nullability; + + StabilityArrayType({ + required this.elementType, + required this.nullability, + }); + + factory StabilityArrayType.fromJson(Map json) => + _$StabilityArrayTypeFromJson(json); + + @override + Map toJson() => { + 'kind': _$StabilityTypeKindEnumMap[StabilityTypeKind.declared], + 'type': _$StabilityArrayTypeToJson(this) + }; +} diff --git a/pkgs/jnigen/lib/src/elements/stability_models.g.dart b/pkgs/jnigen/lib/src/elements/stability_models.g.dart new file mode 100644 index 0000000000..3f144a01cd --- /dev/null +++ b/pkgs/jnigen/lib/src/elements/stability_models.g.dart @@ -0,0 +1,224 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'stability_models.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +StabilityInfo _$StabilityInfoFromJson(Map json) => + StabilityInfo( + formatVersion: Version.parse(json['formatVersion'] as String), + packageName: json['packageName'] as String, + files: (json['files'] as Map).map( + (k, e) => + MapEntry(k, StabilityFile.fromJson(e as Map)), + ), + ); + +Map _$StabilityInfoToJson(StabilityInfo instance) => + { + 'formatVersion': _versionToString(instance.formatVersion), + 'packageName': instance.packageName, + 'files': instance.files, + }; + +StabilityFile _$StabilityFileFromJson(Map json) => + StabilityFile( + classes: (json['classes'] as Map).map( + (k, e) => + MapEntry(k, StabilityClass.fromJson(e as Map)), + ), + ); + +Map _$StabilityFileToJson(StabilityFile instance) => + { + 'classes': instance.classes, + }; + +StabilityClass _$StabilityClassFromJson(Map json) => + StabilityClass( + name: json['name'] as String, + superClass: + StabilityType.fromJson(json['superClass'] as Map), + superInterfaces: (json['superInterfaces'] as List) + .map((e) => StabilityType.fromJson(e as Map)) + .toList(), + fields: (json['fields'] as Map).map( + (k, e) => + MapEntry(k, StabilityField.fromJson(e as Map)), + ), + methods: (json['methods'] as Map).map( + (k, e) => + MapEntry(k, StabilityMethod.fromJson(e as Map)), + ), + typeParameters: (json['typeParameters'] as List) + .map( + (e) => StabilityTypeParameter.fromJson(e as Map)) + .toList(), + ); + +Map _$StabilityClassToJson(StabilityClass instance) => + { + 'name': instance.name, + 'superClass': instance.superClass, + 'superInterfaces': instance.superInterfaces, + 'fields': instance.fields, + 'methods': instance.methods, + 'typeParameters': instance.typeParameters, + }; + +StabilityField _$StabilityFieldFromJson(Map json) => + StabilityField( + name: json['name'] as String, + type: StabilityType.fromJson(json['type'] as Map), + ); + +Map _$StabilityFieldToJson(StabilityField instance) => + { + 'name': instance.name, + 'type': instance.type, + }; + +StabilityMethod _$StabilityMethodFromJson(Map json) => + StabilityMethod( + name: json['name'] as String, + typeParameters: (json['typeParameters'] as List) + .map( + (e) => StabilityTypeParameter.fromJson(e as Map)) + .toList(), + methodParameters: (json['methodParameters'] as List) + .map((e) => + StabilityMethodParameter.fromJson(e as Map)) + .toList(), + returnType: + StabilityType.fromJson(json['returnType'] as Map), + ); + +Map _$StabilityMethodToJson(StabilityMethod instance) => + { + 'name': instance.name, + 'typeParameters': instance.typeParameters, + 'methodParameters': instance.methodParameters, + 'returnType': instance.returnType, + }; + +StabilityMethodParameter _$StabilityMethodParameterFromJson( + Map json) => + StabilityMethodParameter( + name: json['name'] as String, + type: StabilityType.fromJson(json['type'] as Map), + ); + +Map _$StabilityMethodParameterToJson( + StabilityMethodParameter instance) => + { + 'name': instance.name, + 'type': instance.type, + }; + +StabilityTypeParameter _$StabilityTypeParameterFromJson( + Map json) => + StabilityTypeParameter( + name: json['name'] as String, + bounds: (json['bounds'] as List) + .map((e) => StabilityType.fromJson(e as Map)) + .toList(), + ); + +Map _$StabilityTypeParameterToJson( + StabilityTypeParameter instance) => + { + 'name': instance.name, + 'bounds': instance.bounds, + }; + +StabilityPrimitiveType _$StabilityPrimitiveTypeFromJson( + Map json) => + StabilityPrimitiveType( + name: json['name'] as String, + ); + +Map _$StabilityPrimitiveTypeToJson( + StabilityPrimitiveType instance) => + { + 'name': instance.name, + }; + +StabilityTypeVariable _$StabilityTypeVariableFromJson( + Map json) => + StabilityTypeVariable( + name: json['name'] as String, + nullability: $enumDecode(_$NullabilityEnumMap, json['nullability']), + ); + +Map _$StabilityTypeVariableToJson( + StabilityTypeVariable instance) => + { + 'name': instance.name, + 'nullability': _$NullabilityEnumMap[instance.nullability]!, + }; + +const _$NullabilityEnumMap = { + Nullability.nonNullable: 'nonNullable', + Nullability.nullable: 'nullable', + Nullability.platform: 'platform', +}; + +StabilityWildcard _$StabilityWildcardFromJson(Map json) => + StabilityWildcard( + extendsBound: json['extendsBound'] == null + ? null + : StabilityType.fromJson( + json['extendsBound'] as Map), + superBound: json['superBound'] == null + ? null + : StabilityType.fromJson(json['superBound'] as Map), + nullability: $enumDecode(_$NullabilityEnumMap, json['nullability']), + ); + +Map _$StabilityWildcardToJson(StabilityWildcard instance) => + { + 'extendsBound': instance.extendsBound, + 'superBound': instance.superBound, + 'nullability': _$NullabilityEnumMap[instance.nullability]!, + }; + +StabilityDeclaredType _$StabilityDeclaredTypeFromJson( + Map json) => + StabilityDeclaredType( + binaryName: json['binaryName'] as String, + typeArguments: (json['typeArguments'] as List) + .map((e) => StabilityType.fromJson(e as Map)) + .toList(), + nullability: $enumDecode(_$NullabilityEnumMap, json['nullability']), + ); + +Map _$StabilityDeclaredTypeToJson( + StabilityDeclaredType instance) => + { + 'binaryName': instance.binaryName, + 'typeArguments': instance.typeArguments, + 'nullability': _$NullabilityEnumMap[instance.nullability]!, + }; + +StabilityArrayType _$StabilityArrayTypeFromJson(Map json) => + StabilityArrayType( + elementType: + StabilityType.fromJson(json['elementType'] as Map), + nullability: $enumDecode(_$NullabilityEnumMap, json['nullability']), + ); + +Map _$StabilityArrayTypeToJson(StabilityArrayType instance) => + { + 'elementType': instance.elementType, + 'nullability': _$NullabilityEnumMap[instance.nullability]!, + }; + +const _$StabilityTypeKindEnumMap = { + StabilityTypeKind.primitive: 'primitive', + StabilityTypeKind.typeVariable: 'typeVariable', + StabilityTypeKind.wildcard: 'wildcard', + StabilityTypeKind.declared: 'declared', + StabilityTypeKind.array: 'array', +}; diff --git a/pkgs/jnigen/lib/src/generate_bindings.dart b/pkgs/jnigen/lib/src/generate_bindings.dart index d49c84740f..01da43a1cd 100644 --- a/pkgs/jnigen/lib/src/generate_bindings.dart +++ b/pkgs/jnigen/lib/src/generate_bindings.dart @@ -4,20 +4,21 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:io'; import 'bindings/dart_generator.dart'; -import 'bindings/excluder.dart'; +import 'bindings/exporter.dart'; +import 'bindings/graph_builder.dart'; +import 'bindings/importer.dart'; import 'bindings/kotlin_processor.dart'; import 'bindings/linker.dart'; -import 'bindings/renamer.dart'; import 'bindings/visitor.dart'; import 'config/config.dart'; import 'elements/elements.dart'; -import 'elements/j_elements.dart' as j_ast; import 'logging/logging.dart'; import 'summary/summary.dart'; import 'tools/tools.dart'; +import 'transformers/default_renamer.dart'; +import 'transformers/graph.dart'; void collectOutputStream(Stream> stream, StringBuffer buffer) => stream.transform(const Utf8Decoder()).forEach(buffer.write); @@ -40,28 +41,28 @@ Future generateJniBindings(Config config) async { log.fatal(e.message); } - final userClasses = j_ast.Classes(classes); - config.visitors?.forEach(userClasses.accept); - // Keep the order in sync with `elements/elements.dart`. - var stage = GenerationStage.userVisitors; + var stage = GenerationStage.unprocessed; R runStage(TopLevelVisitor visitor) { assert(visitor.stage.index == stage.index + 1); stage = visitor.stage; return classes.accept(visitor); } - runStage(Excluder(config)); + void runUserTransformersStage(Bindings bindings) { + assert(GenerationStage.userTransformers.index == stage.index + 1); + stage = GenerationStage.userTransformers; + config.visitors?.forEach(bindings.accept); + // FIXME + bindings.accept(DefaultRenamer(config)); + } + runStage(KotlinProcessor()); + await runStage(Importer(config)); await runStage(Linker(config)); - runStage(Renamer(config)); + final bindings = runStage(GraphBuilder(config)); + runUserTransformersStage(bindings); + await runStage(Exporter(config)); + await runStage(DartGenerator(config)); // classes.accept(const Printer()); - - try { - await classes.accept(DartGenerator(config)); - log.info('Completed'); - } on Exception catch (e, trace) { - stderr.writeln(trace); - log.fatal('Error while writing bindings: $e'); - } } diff --git a/pkgs/jnigen/lib/src/transformers/default_excluder.dart b/pkgs/jnigen/lib/src/transformers/default_excluder.dart new file mode 100644 index 0000000000..e992f0432d --- /dev/null +++ b/pkgs/jnigen/lib/src/transformers/default_excluder.dart @@ -0,0 +1,95 @@ +// // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// // for details. All rights reserved. Use of this source code is governed by a +// // BSD-style license that can be found in the LICENSE file. + +// import '../config/config.dart'; +// import '../elements/elements.dart'; +// import '../logging/logging.dart'; +// import 'visitor.dart'; + +// extension on HasModifiers { +// bool get isPrivate => !isPublic; +// } + +// // TODO(https://github.com/dart-lang/native/issues/1164): Kotlin compiler +// // appends the method name with a dash and a hash code when arguments contain +// // inline classes. This is because inline classes do not have any runtime type +// // and the typical operator overloading supported by JVM cannot work for them. +// // +// // Once we support inline classes, we can relax the following constraints. +// final _validDartIdentifier = RegExp(r'^[a-zA-Z_$][a-zA-Z0-9_$]*$'); + +// extension on String { +// bool get isInvalidDartIdentifier => +// !_validDartIdentifier.hasMatch(this) && +// this != '' && +// this != ''; +// } + +// class Excluder extends ElementVisitor with TopLevelVisitor { +// @override +// final stage = GenerationStage.excluder; + +// final Config config; + +// const Excluder(this.config); + +// @override +// void visit(Classes node) { +// node.decls.removeWhere((_, classDecl) { +// final excluded = classDecl.isPrivate || classDecl.isExcluded; +// if (excluded) { +// log.fine('Excluded class ${classDecl.binaryName}'); +// } +// if (classDecl.name.isInvalidDartIdentifier) { +// log.warning('Excluded class ${classDecl.binaryName}: the name is not a' +// ' valid Dart identifer'); +// return true; +// } +// return excluded; +// }); +// final classExcluder = _ClassExcluder(config); +// for (final classDecl in node.decls.values) { +// classDecl.accept(classExcluder); +// } +// } +// } + +// class _ClassExcluder extends ElementVisitor { +// final Config config; + +// _ClassExcluder(this.config); + +// @override +// void visit(ClassDecl node) { +// node.methods = node.methods.where((method) { +// final isPrivate = method.isPrivate; +// final isAbstractCtor = method.isConstructor && node.isAbstract; +// final isBridgeMethod = method.isSynthetic && method.isBridge; +// final excluded = isPrivate || isAbstractCtor || isBridgeMethod; +// if (excluded) { +// log.fine('Excluded method ${node.binaryName}#${method.name}'); +// } +// if (method.name.isInvalidDartIdentifier) { +// log.warning( +// 'Excluded method ${node.binaryName}#${method.name}: the name is not' +// ' a valid Dart identifer'); +// return false; +// } +// return !excluded; +// }).toList(); +// node.fields = node.fields.where((field) { +// final excluded = field.isExcluded || field.isPrivate; +// if (excluded) { +// log.fine('Excluded field ${node.binaryName}#${field.name}'); +// } +// if (field.name.isInvalidDartIdentifier) { +// log.warning( +// 'Excluded field ${node.binaryName}#${field.name}: the name is not' +// ' a valid Dart identifer'); +// return false; +// } +// return !excluded; +// }).toList(); +// } +// } diff --git a/pkgs/jnigen/lib/src/transformers/default_renamer.dart b/pkgs/jnigen/lib/src/transformers/default_renamer.dart new file mode 100644 index 0000000000..fe5b7ffa55 --- /dev/null +++ b/pkgs/jnigen/lib/src/transformers/default_renamer.dart @@ -0,0 +1,158 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import '../config/config.dart'; +import '../logging/logging.dart'; +import 'graph.dart'; + +final class DefaultRenamer extends Visitor { + final Config config; + + DefaultRenamer(this.config); + + final _nodeToUsedNames = >{}; + final _validDartIdentifierCharacters = RegExp(r'[a-zA-Z0-9_$]'); + + String _preprocess(String name) { + // Replaces the `_` prefix with `$_` to prevent hiding public members. + String makePublic(String name) => + name.startsWith('_') ? '\$_${name.substring(1)}' : name; + + // Replaces each dollar sign with two dollar signs in [name]. + // For example `$foo$$bar$` -> `$$foo$$$$bar$$`. + String doubleDollarSigns(String name) => name.replaceAll(r'$', r'$$'); + + // Replaces each disallowed characters with an underscore. + String removeDisallowedChars(String name) { + final newName = StringBuffer(); + for (var i = 0; i < name.length; ++i) { + final char = name[i]; + if (_validDartIdentifierCharacters.hasMatch(char)) { + newName.write(char); + } else { + newName.write('_'); + } + } + return newName.toString(); + } + + return makePublic(doubleDollarSigns(removeDisallowedChars(name))); + } + + final _countRegexp = RegExp(r'^(.*)\$(\d+)?$'); + + Set _usedNamesIn(Object node) { + return _nodeToUsedNames[node] ??= {}; + } + + // FIXME: return string, get a bool function for isNameAllowed. + void _renameConflict(dynamic renamable, Object parent) { + final usedNames = _usedNamesIn(parent); + // ignore: avoid_dynamic_calls - Using dynamic as `_Renamable` is private. + var name = renamable.name as String; + // ignore: avoid_dynamic_calls + if (!(renamable.isNameAllowed(name) as bool)) { + // Try appending a dollar sign if the name is a Dart keyword or a + // disallowed identifier. + name = '$name\$'; + } + final regexMatch = _countRegexp.firstMatch(name); + final String namePart; + int countPart; + if (regexMatch != null) { + namePart = regexMatch[1]!; + countPart = int.parse(regexMatch[2] ?? '0'); + } else { + namePart = name; + countPart = 0; + } + while (usedNames.contains(name)) { + countPart += 1; + name = '$namePart\$$countPart'; + } + // ignore: avoid_dynamic_calls + renamable.name = name; + usedNames.add(name); + } + + @override + void visitClass(Class cls) { + if (cls.stableName case final stableName?) { + cls.name = stableName; + log.finest('Used the stable name "$stableName" for class "$cls".'); + _usedNamesIn(cls.enclosingFile).add(cls.name!); + } else { + cls.name = _preprocess(cls.originalName); + if (cls.enclosingClass != null) { + cls.name = '${cls.enclosingClass!.name}\$${cls.name}'; + } + _renameConflict(cls, cls.enclosingFile); + } + for (final property in cls.properties) { + if (property.name != null) { + _usedNamesIn(cls).add(property.name!); + } else if (property.stableName case final stableName?) { + property.name = stableName; + log.finest( + 'Used the stable name "$stableName" for property "$property" of ' + 'class "${property.enclosingClass}".'); + _usedNamesIn(cls).add(property.name!); + } + } + for (final method in cls.methods) { + if (method.name != null) { + _usedNamesIn(cls).add(method.name!); + } else if (method.stableName case final stableName?) { + method.name = stableName; + log.finest('Used the stable name "$stableName" for method "$method" of ' + 'class "${method.enclosingClass}".'); + _usedNamesIn(cls).add(method.name!); + } + } + super.visitClass(cls); + } + + @override + void visitProperty(Property property) { + final parent = property.enclosingClass.isTopLevel + ? property.enclosingClass.enclosingFile + : property.enclosingClass; + if (property.name != null) { + return; + } + property.name = _preprocess(property.originalName); + _renameConflict(property, parent); + } + + @override + void visitMethod(Method method) { + final parent = method.enclosingClass.isTopLevel + ? method.enclosingClass.enclosingFile + : method.enclosingClass; + if (method.name != null) { + return super.visitMethod(method); + } + method.name = _preprocess(method.originalName); + _renameConflict(method, parent); + final b = method.enclosingClass.identifier == + 'com.github.dart_lang.jnigen.inheritance.DerivedInterface'; + if (b) log.warning('method $method is named ${method.name}'); + super.visitMethod(method); + } + + @override + void visitMethodParameter(MethodParameter methodParameter) { + if (methodParameter.stableName case final stableName?) { + methodParameter.name = stableName; + log.finest('Used the stable name "$stableName" for method parameter ' + 'at index ${methodParameter.identifier} of method ' + '"${methodParameter.enclosingMethod}" of ' + 'class "${methodParameter.enclosingMethod.enclosingClass}"'); + _usedNamesIn(methodParameter.enclosingMethod).add(methodParameter.name!); + } else { + methodParameter.name = _preprocess(methodParameter.originalName); + _renameConflict(methodParameter, methodParameter.enclosingMethod); + } + } +} diff --git a/pkgs/jnigen/lib/src/transformers/graph.dart b/pkgs/jnigen/lib/src/transformers/graph.dart new file mode 100644 index 0000000000..7a48c8a08d --- /dev/null +++ b/pkgs/jnigen/lib/src/transformers/graph.dart @@ -0,0 +1,420 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:collection'; + +import 'package:meta/meta.dart' as meta show internal; + +import '../elements/elements.dart' as internal; + +const _disallowedAsClassName = { + 'abstract', + 'covariant', + 'deferred', + 'dynamic', + 'export', + 'extension', + 'external', + 'factory', + 'Function', + 'implements', + 'interface', + 'late', + 'library', + 'mixin', + 'operator', + 'part', + 'required', + 'static', + 'typedef', +}; + +const _keywords = { + 'assert', + 'await', // Cannot be used in async context. + 'break', + 'case', + 'catch', + 'class', + 'const', + 'continue', + 'default', + 'do', + 'else', + 'enum', + 'extends', + 'false', + 'final', + 'finally', + 'for', + 'if', + 'import', + 'in', + 'is', + 'new', + 'null', + 'rethrow', + 'return', + 'super', + 'switch', + 'this', + 'throw', + 'true', + 'try', + 'var', + 'void', + 'while', + 'with', + 'yield', // Cannot be used in async context. +}; + +const _disallowedInInterface = { + 'implement', + 'implementIn', +}; + +final _validDartIdentifier = RegExp(r'^[a-zA-Z_$][a-zA-Z0-9_$]*$'); + +abstract class Visitor { + void visit(Bindings bindings) { + bindings.visitChildren(this); + } + + void visitClass(Class cls) { + cls.visitChildren(this); + } + + void visitProperty(Property property) {} + + void visitMethod(Method method) { + method.visitChildren(this); + } + + void visitMethodParameter(MethodParameter methodParameter) {} +} + +abstract final class _Node> { + final T _internalNode; + + _Node(this._internalNode); +} + +base mixin _Visitable { + void accept(Visitor visitor); +} + +base mixin _HasVisitableChildren { + void visitChildren(Visitor visitor); +} + +base mixin _HasModifiers> on _Node { + bool get isAbstract => _internalNode.isAbstract; + bool get isStatic => _internalNode.isStatic; + bool get isFinal => _internalNode.isFinal; + bool get isPublic => _internalNode.isPublic; + bool get isProtected => _internalNode.isProtected; + bool get isSynthetic => _internalNode.isSynthetic; + bool get isBridge => _internalNode.isBridge; +} + +base mixin _Renamable> on _Node { + /// The name that will uniquely identify this element between in the context + /// of its parent node. + String get identifier; + + /// The original name of the element in the source language. + String get originalName => _internalNode.originalName; + + /// The name loaded from the API stability file. + /// + /// This will be `null` if the element was not found in the API stability + /// file, for example, when running for the first time or after a new element + /// is added. + String? get stableName => _internalNode.stableName; + + /// The current name of the element. This will be used in the generated + /// bindings. + /// + /// Setting is subject to validation. + String? get name => _internalNode.finalName; + + set name(String? newName) { + _internalNode.finalName = newName; + } + + /// Whether the given name is allowed for this element. + /// + /// Returns `false` if the name is a Dart keyword or cannot be syntactically + /// the name of this element due to name collision. + bool isNameAllowed(String name); +} + +base mixin _Excludable> on _Node { + /// Whether this element is excluded from the generated bindings. + bool get isExcluded => _internalNode.isExcluded; + + set isExcluded(bool isExcluded) { + _internalNode.isExcluded = isExcluded; + } +} + +/// This class represents the entire set of generated code for a single +/// JNIgen run. It's the main entry point for any user-defined transformations. +final class Bindings extends _Node + with _Visitable, _HasVisitableChildren { + @meta.internal + Bindings(super._internalNode, this._classes, this._files); + + /// Stored in topological order of the classes. + final Map _classes; + final Map _files; + + Iterable get classes => _classes.values; + Iterable get files => _files.values; + + @override + void accept(Visitor visitor) { + visitor.visit(this); + } + + @override + void visitChildren(Visitor visitor) { + for (final cls in classes) { + cls.accept(visitor); + } + } +} + +/// Represents a Dart file. +final class DartFile extends _Node + with _HasVisitableChildren { + final Map _classes; + + @meta.internal + DartFile(super._internalNode, this._classes) { + for (final cls in classes) { + cls.enclosingFile = this; + } + } + + String get path => _internalNode.path; + + Iterable get classes => _classes.values; + + @override + void visitChildren(Visitor visitor) { + for (final cls in classes) { + cls.accept(visitor); + } + } +} + +enum Language { + java, + kotlin, +} + +enum DeclKind { + /// Declared as a normal class. + classKind, + + /// Declared as an interface. + interfaceKind, + + /// Declared as an enum. + enumKind, + + /// Declared as a collection of top-level methods and properties. + packageKind, +} + +/// Represents a Dart class or a collection of top-level methods and properties. +final class Class extends _Node + with + _Visitable, + _HasVisitableChildren, + _Renamable, + _Excludable, + _HasModifiers { + @meta.internal + Class(super._internalNode, this._properties, this._methods) { + for (final property in _properties.values) { + property.enclosingClass = this; + } + for (final method in _methods.values) { + method.enclosingClass = this; + } + } + + /// The [DartFile] that this class is a part of. + late final DartFile enclosingFile; + + /// The outer class of this class or `null` if this class is not nested. + late final Class? enclosingClass; + + /// Map from name to field. + /// + /// The entries are ordered the same way as [internal.ClassDecl.fields]. + final Map _properties; + + /// Map from (name + signature) to method. + /// + /// The entries are ordered the same way as [internal.ClassDecl.methods]. + final Map _methods; + + Iterable get properties => _properties.values; + Iterable get methods => _methods.values; + + /// The programming language of origin. + Language get language { + return _internalNode.kotlinClass != null || + _internalNode.kotlinPackage != null + ? Language.kotlin + : Language.java; + } + + /// The original declaration type of this class. + DeclKind get kind { + if (_internalNode.kotlinPackage != null) return DeclKind.packageKind; + return switch (_internalNode.declKind) { + internal.DeclKind.classKind => DeclKind.classKind, + internal.DeclKind.interfaceKind => DeclKind.interfaceKind, + internal.DeclKind.enumKind => DeclKind.enumKind, + }; + } + + /// Whether the class is actually only a number of top-level functions + /// and properties. + bool get isTopLevel => _internalNode.isTopLevel; + + set isTopLevel(bool isTopLevel) { + _internalNode.isTopLevel = isTopLevel; + } + + @override + void accept(Visitor visitor) { + visitor.visitClass(this); + } + + @override + void visitChildren(Visitor visitor) { + for (final method in methods) { + method.accept(visitor); + } + for (final property in properties) { + property.accept(visitor); + } + } + + @override + bool isNameAllowed(String name) { + return _validDartIdentifier.hasMatch(name) && + !_disallowedAsClassName.contains(name) && + !_keywords.contains(name); + } + + @override + String get identifier => _internalNode.binaryName; + + @override + String toString() => identifier; +} + +/// Represents a logical property, which may have a getter, a setter, or both. +final class Property extends _Node + with _Visitable, _Renamable, _Excludable, _HasModifiers { + @meta.internal + Property(super._internalNode); + + late final Class enclosingClass; + + @override + void accept(Visitor visitor) { + visitor.visitProperty(this); + } + + @override + bool isNameAllowed(String name) { + if (enclosingClass.kind == DeclKind.interfaceKind && + _disallowedInInterface.contains(name)) { + return false; + } + return _validDartIdentifier.hasMatch(name) && !_keywords.contains(name); + } + + @override + String get identifier => originalName; + + @override + String toString() => identifier; +} + +/// Represents a Dart method. +final class Method extends _Node + with + _Visitable, + _HasVisitableChildren, + _Renamable, + _Excludable, + _HasModifiers { + @meta.internal + Method(super._internalNode, this.parameters) { + for (final param in parameters) { + param.enclosingMethod = this; + } + } + + late final Class enclosingClass; + final UnmodifiableListView parameters; + + @override + void accept(Visitor visitor) { + visitor.visitMethod(this); + } + + @override + void visitChildren(Visitor visitor) { + for (final parameter in parameters) { + parameter.accept(visitor); + } + } + + @override + bool isNameAllowed(String name) { + if (enclosingClass.kind == DeclKind.interfaceKind && + _disallowedInInterface.contains(name)) { + return false; + } + return _validDartIdentifier.hasMatch(name) && !_keywords.contains(name); + } + + @override + String get identifier => _internalNode.javaSig; + + @override + String toString() => identifier; +} + +/// Represents a parameter of a [Method]. +final class MethodParameter extends _Node + with _Visitable, _Renamable { + @meta.internal + MethodParameter(super._internalNode); + + late final Method enclosingMethod; + + @override + void accept(Visitor visitor) { + visitor.visitMethodParameter(this); + } + + @override + bool isNameAllowed(String name) { + return _validDartIdentifier.hasMatch(name) && !_keywords.contains(name); + } + + @override + String get identifier => + _internalNode.method.params.indexOf(_internalNode).toString(); +} diff --git a/pkgs/jnigen/lib/src/transformers/validator.dart b/pkgs/jnigen/lib/src/transformers/validator.dart new file mode 100644 index 0000000000..9e9ad9a615 --- /dev/null +++ b/pkgs/jnigen/lib/src/transformers/validator.dart @@ -0,0 +1,158 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'graph.dart'; + +final class ValidationError extends Error { + final String message; + + ValidationError(this.message); + + @override + String toString() => 'Validation error: $message'; +} + +final class Validator extends Visitor { + String _usedNameClusters(Map> usedNames) { + final usedNameClusters = StringBuffer(); + for (final MapEntry(key: name, value: identifiers) in usedNames.entries) { + if (identifiers.length > 1) { + usedNameClusters.write('\n\n"$name": \n- '); + usedNameClusters.writeAll(identifiers, '\n- '); + } + } + return usedNameClusters.toString(); + } + + @override + void visit(Bindings bindings) { + for (final file in bindings.files) { + final usedNames = >{}; + for (final cls in file.classes) { + if (cls.name == null) { + throw ValidationError('No name has been provided for $cls.'); + } + (usedNames[cls.name!] ??= []).add(cls.identifier); + } + final usedNameClusters = _usedNameClusters(usedNames); + final hasValidNaming = usedNameClusters.isEmpty; + if (!hasValidNaming) { + throw ValidationError(''' +The following members are named the same in file "${file.path}":$usedNameClusters + +To fix the problem, choose different names for the classes. +'''); + } + } + } + + @override + void visitClass(Class cls) { + if (!cls.isNameAllowed(cls.name!)) { + throw ValidationError( + 'The class "$cls" cannot have the name "${cls.name}".'); + } + if (cls.isTopLevel && cls.kind != DeclKind.packageKind) { + // Validate whether this class can be top-level. + final includedNonStaticProperties = cls.properties + .where((property) => !property.isExcluded && !property.isStatic); + final includedNonStaticMethods = + cls.methods.where((method) => !method.isExcluded && !method.isStatic); + if (includedNonStaticProperties.isNotEmpty || + includedNonStaticMethods.isNotEmpty) { + final instanceMembers = [ + ...includedNonStaticMethods, + ...includedNonStaticProperties + ].map((member) => '- $member').join('\n'); + throw ValidationError(''' +Class "$cls" cannot be converted to a top-level container as it has non-excluded +instance members: + +$instanceMembers + +To fix this problem, either set isTopLevel to false, or exclude all of the +instance members of this class. +'''); + } + } + // Validate the namings of included members. + final usedNames = >{}; + for (final property in cls.properties) { + if (property.name == null) { + throw ValidationError( + 'No name has been provided for property $property of class ' + '${property.enclosingClass}.'); + } + (usedNames[property.name!] ??= []).add(property.identifier); + } + for (final method in cls.methods) { + if (method.name == null) { + throw ValidationError( + 'No name has been provided for method $method of class ' + '${method.enclosingClass}.'); + } + (usedNames[method.name!] ??= []).add(method.identifier); + } + final usedNameClusters = _usedNameClusters(usedNames); + final hasValidNaming = usedNameClusters.isEmpty; + if (!hasValidNaming) { + throw ValidationError(''' +The following members are named the same in class "$cls":$usedNameClusters + +To fix the problem, choose different names for the members. +'''); + } + super.visitClass(cls); + } + + @override + void visitProperty(Property property) { + if (!property.isNameAllowed(property.name!)) { + throw ValidationError(''' +The property "$property" of class "${property.enclosingClass}" cannot have the +name "${property.name}". +'''); + } + } + + @override + void visitMethod(Method method) { + if (!method.isNameAllowed(method.name!)) { + throw ValidationError(''' +The method "$method" of class "${method.enclosingClass}" cannot have the +name "${method.name}". +'''); + } + final usedNames = {}; + for (final parameter in method.parameters) { + if (parameter.name == null) { + throw ValidationError( + 'No name has been provided for parameter $parameter of method ' + '${parameter.enclosingMethod} of class ' + '${parameter.enclosingMethod.enclosingClass}.'); + } + if (usedNames.contains(parameter.name)) { + throw ValidationError(''' +The parameter names of method "$method" of class "${method.enclosingClass}" +clash with one another. + +To fix the problem, choose different names for the parameters. +'''); + } + } + super.visitMethod(method); + } + + @override + void visitMethodParameter(MethodParameter methodParameter) { + if (!methodParameter.isNameAllowed(methodParameter.name!)) { + final method = methodParameter.enclosingMethod; + final enclosingClass = method.enclosingClass; + throw ValidationError(''' +The parameter at index $methodParameter of method "$method" of class +"$enclosingClass" cannot have the name "${methodParameter.name}". +'''); + } + } +} diff --git a/pkgs/jnigen/test/package_resolver_test.dart b/pkgs/jnigen/test/package_resolver_test.dart deleted file mode 100644 index 59595522e2..0000000000 --- a/pkgs/jnigen/test/package_resolver_test.dart +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:jnigen/src/bindings/resolver.dart'; -import 'package:jnigen/src/elements/elements.dart'; -import 'package:test/test.dart'; - -import 'test_util/test_util.dart'; - -class ResolverTest { - ResolverTest(this.binaryName, this.expectedImport, this.expectedName); - String binaryName; - String expectedImport; - String expectedName; -} - -void main() async { - await checkLocallyBuiltDependencies(); - final resolver = Resolver( - importedClasses: { - 'org.apache.pdfbox.pdmodel.PDDocument': ClassDecl( - declKind: DeclKind.classKind, - binaryName: 'org.apache.pdfbox.pdmodel.PDDocument', - )..path = 'package:pdfbox/pdfbox.dart', - 'android.os.Process': ClassDecl( - declKind: DeclKind.classKind, - binaryName: 'android.os.Process', - )..path = 'package:android/os.dart', - }, - currentClass: 'a.b.N', - inputClassNames: { - 'a.b.C', - 'a.b.c.D', - 'a.b.c.d.E', - 'a.X', - 'e.f.G', - 'e.F', - 'a.g.Y', - 'a.m.n.P' - }, - ); - - final tests = [ - // Absolute imports resolved using import map - ResolverTest( - 'android.os.Process', 'package:android/os.dart', r'process$_.'), - ResolverTest('org.apache.pdfbox.pdmodel.PDDocument', - 'package:pdfbox/pdfbox.dart', r'pddocument$_.'), - // Relative imports - // inner package - ResolverTest('a.b.c.D', 'c/D.dart', r'd$_.'), - // inner package, deeper - ResolverTest('a.b.c.d.E', 'c/d/E.dart', r'e$_.'), - // parent package - ResolverTest('a.X', '../X.dart', r'x$_.'), - // unrelated package in same translation unit - ResolverTest('e.f.G', '../../e/f/G.dart', r'g$_.'), - ResolverTest('e.F', '../../e/F.dart', r'f$_.'), - // neighbour package - ResolverTest('a.g.Y', '../g/Y.dart', r'y$_.'), - // inner package of a neighbour package - ResolverTest('a.m.n.P', '../m/n/P.dart', r'p$_.'), - ]; - - for (var testCase in tests) { - final binaryName = testCase.binaryName; - final packageName = Resolver.getFileClassName(binaryName); - test( - 'getImport $binaryName', - () => expect(resolver.getImport(packageName, binaryName), - equals(testCase.expectedImport))); - test( - 'resolve $binaryName', - () => expect( - resolver.resolvePrefix(ClassDecl( - declKind: DeclKind.classKind, - binaryName: binaryName, - )..path = ''), - equals(testCase.expectedName))); - } -} diff --git a/pkgs/jnigen/test/renamer_test.dart b/pkgs/jnigen/test/renamer_test.dart index 1da7f185b8..a026530662 100644 --- a/pkgs/jnigen/test/renamer_test.dart +++ b/pkgs/jnigen/test/renamer_test.dart @@ -4,11 +4,11 @@ import 'package:jnigen/jnigen.dart'; import 'package:jnigen/src/bindings/linker.dart'; -import 'package:jnigen/src/bindings/renamer.dart'; +// import 'package:jnigen/src/bindings/renamer.dart'; import 'package:test/test.dart'; -extension on Iterable { - List get finalNames => map((c) => c.finalName).toList(); +extension on Iterable { + List get finalNames => map((c) => c.finalName!).toList(); } Future rename(Classes classes) async { @@ -22,7 +22,7 @@ Future rename(Classes classes) async { classes: [], ); await classes.accept(Linker(config)); - classes.accept(Renamer(config)); + // classes.accept(Renamer(config)); } void main() { diff --git a/pkgs/jnigen/test/simple_package_test/bindings/simple_package.dart b/pkgs/jnigen/test/simple_package_test/bindings/simple_package.dart index 7969db39a4..78900ed167 100644 --- a/pkgs/jnigen/test/simple_package_test/bindings/simple_package.dart +++ b/pkgs/jnigen/test/simple_package_test/bindings/simple_package.dart @@ -38,6 +38,7 @@ import 'dart:core' show Object, String, bool, double, int; import 'dart:core' as core$_; import 'package:jni/_internal.dart' as jni$_; + import 'package:jni/jni.dart' as jni$_; /// from: `com.github.dart_lang.jnigen.simple_package.Example$Nested$NestedTwice` @@ -97,6 +98,29 @@ class Example$Nested$NestedTwice extends jni$_.JObject { _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr) .reference); } + + static final _id_$_clinit_ = _class.staticMethodId( + r'', + r'()V', + ); + + static final _$_clinit_ = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallStaticVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `static void ()` + static void $_clinit_() { + _$_clinit_(_class.reference.pointer, _id_$_clinit_ as jni$_.JMethodIDPtr) + .check(); + } } final class $Example$Nested$NestedTwice$NullableType$ @@ -199,6 +223,18 @@ class Example$Nested extends jni$_.JObject { /// The type which includes information such as the signature of this class. static const jni$_.JType type = $Example$Nested$Type$(); + static final _id_value = _class.instanceFieldId( + r'value', + r'Z', + ); + + /// from: `private boolean value` + bool get value => _id_value.get(this, const jni$_.jbooleanType()); + + /// from: `private boolean value` + set value(bool value) => + _id_value.set(this, const jni$_.jbooleanType(), value); + static final _id_new$ = _class.constructorId( r'(Z)V', ); @@ -421,11 +457,11 @@ class Example$NonStaticNested extends jni$_.JObject { /// from: `public void (com.github.dart_lang.jnigen.simple_package.Example $outerClass)` /// The returned object must be released after use, by calling the [release] method. factory Example$NonStaticNested( - Example $outerClass, + Example $$outerClass, ) { - final _$$outerClass = $outerClass.reference; + final _$$$outerClass = $$outerClass.reference; return Example$NonStaticNested.fromReference(_new$(_class.reference.pointer, - _id_new$ as jni$_.JMethodIDPtr, _$$outerClass.pointer) + _id_new$ as jni$_.JMethodIDPtr, _$$$outerClass.pointer) .reference); } } @@ -561,6 +597,139 @@ class Example extends jni$_.JObject { static jni$_.JObject? get unusedRandom => _id_unusedRandom.get(_class, const jni$_.$JObject$NullableType$()); + static final _id_amount = _class.staticFieldId( + r'amount', + r'I', + ); + + /// from: `private static int amount` + static int get amount => _id_amount.get(_class, const jni$_.jintType()); + + /// from: `private static int amount` + static set amount(int value) => + _id_amount.set(_class, const jni$_.jintType(), value); + + static final _id_pi = _class.staticFieldId( + r'pi', + r'D', + ); + + /// from: `private static double pi` + static double get pi => _id_pi.get(_class, const jni$_.jdoubleType()); + + /// from: `private static double pi` + static set pi(double value) => + _id_pi.set(_class, const jni$_.jdoubleType(), value); + + static final _id_asterisk = _class.staticFieldId( + r'asterisk', + r'C', + ); + + /// from: `private static char asterisk` + static int get asterisk => _id_asterisk.get(_class, const jni$_.jcharType()); + + /// from: `private static char asterisk` + static set asterisk(int value) => + _id_asterisk.set(_class, const jni$_.jcharType(), value); + + static final _id_name = _class.staticFieldId( + r'name', + r'Ljava/lang/String;', + ); + + /// from: `private static java.lang.String name` + /// The returned object must be released after use, by calling the [release] method. + static jni$_.JString? get name => + _id_name.get(_class, const jni$_.$JString$NullableType$()); + + /// from: `private static java.lang.String name` + /// The returned object must be released after use, by calling the [release] method. + static set name(jni$_.JString? value) => + _id_name.set(_class, const jni$_.$JString$NullableType$(), value); + + static final _id_nested = _class.staticFieldId( + r'nested', + r'Lcom/github/dart_lang/jnigen/simple_package/Example$Nested;', + ); + + /// from: `private static com.github.dart_lang.jnigen.simple_package.Example$Nested nested` + /// The returned object must be released after use, by calling the [release] method. + static Example$Nested? get nested => + _id_nested.get(_class, const $Example$Nested$NullableType$()); + + /// from: `private static com.github.dart_lang.jnigen.simple_package.Example$Nested nested` + /// The returned object must be released after use, by calling the [release] method. + static set nested(Example$Nested? value) => + _id_nested.set(_class, const $Example$Nested$NullableType$(), value); + + static final _id_number = _class.instanceFieldId( + r'number', + r'I', + ); + + /// from: `private int number` + int get number => _id_number.get(this, const jni$_.jintType()); + + /// from: `private int number` + set number(int value) => _id_number.set(this, const jni$_.jintType(), value); + + static final _id_isUp = _class.instanceFieldId( + r'isUp', + r'Z', + ); + + /// from: `private boolean isUp` + bool get isUp => _id_isUp.get(this, const jni$_.jbooleanType()); + + /// from: `private boolean isUp` + set isUp(bool value) => _id_isUp.set(this, const jni$_.jbooleanType(), value); + + static final _id_codename = _class.instanceFieldId( + r'codename', + r'Ljava/lang/String;', + ); + + /// from: `private java.lang.String codename` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? get codename => + _id_codename.get(this, const jni$_.$JString$NullableType$()); + + /// from: `private java.lang.String codename` + /// The returned object must be released after use, by calling the [release] method. + set codename(jni$_.JString? value) => + _id_codename.set(this, const jni$_.$JString$NullableType$(), value); + + static final _id_random = _class.instanceFieldId( + r'random', + r'Ljava/util/Random;', + ); + + /// from: `private java.util.Random random` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? get random => + _id_random.get(this, const jni$_.$JObject$NullableType$()); + + /// from: `private java.util.Random random` + /// The returned object must be released after use, by calling the [release] method. + set random(jni$_.JObject? value) => + _id_random.set(this, const jni$_.$JObject$NullableType$(), value); + + static final _id_protectedField = _class.instanceFieldId( + r'protectedField', + r'Ljava/util/Random;', + ); + + /// from: `protected java.util.Random protectedField` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? get protectedField => + _id_protectedField.get(this, const jni$_.$JObject$NullableType$()); + + /// from: `protected java.util.Random protectedField` + /// The returned object must be released after use, by calling the [release] method. + set protectedField(jni$_.JObject? value) => + _id_protectedField.set(this, const jni$_.$JObject$NullableType$(), value); + static final _id_getAmount = _class.staticMethodId( r'getAmount', r'()I', @@ -1147,6 +1316,77 @@ class Example extends jni$_.JObject { .object(const jni$_.$JString$NullableType$()); } + static final _id_privateMethod = _class.instanceMethodId( + r'privateMethod', + r'(Ljava/lang/String;Ljava/lang/String;)V', + ); + + static final _privateMethod = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `private void privateMethod(java.lang.String string, java.lang.String string1)` + void privateMethod( + jni$_.JString? string, + jni$_.JString? string1, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + final _$string1 = string1?.reference ?? jni$_.jNullReference; + _privateMethod(reference.pointer, _id_privateMethod as jni$_.JMethodIDPtr, + _$string.pointer, _$string1.pointer) + .check(); + } + + static final _id_protectedMethod = _class.instanceMethodId( + r'protectedMethod', + r'(Ljava/lang/String;Ljava/lang/String;)V', + ); + + static final _protectedMethod = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `protected void protectedMethod(java.lang.String string, java.lang.String string1)` + void protectedMethod( + jni$_.JString? string, + jni$_.JString? string1, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + final _$string1 = string1?.reference ?? jni$_.jNullReference; + _protectedMethod( + reference.pointer, + _id_protectedMethod as jni$_.JMethodIDPtr, + _$string.pointer, + _$string1.pointer) + .check(); + } + static final _id_finalMethod = _class.instanceMethodId( r'finalMethod', r'()V', @@ -1719,6 +1959,29 @@ class Example extends jni$_.JObject { _$list.pointer) .check(); } + + static final _id_$_clinit_ = _class.staticMethodId( + r'', + r'()V', + ); + + static final _$_clinit_ = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallStaticVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `static void ()` + static void $_clinit_() { + _$_clinit_(_class.reference.pointer, _id_$_clinit_ as jni$_.JMethodIDPtr) + .check(); + } } final class $Example$NullableType$ extends jni$_.JType { @@ -2396,6 +2659,29 @@ class Fields$Nested extends jni$_.JObject { _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr) .reference); } + + static final _id_$_clinit_ = _class.staticMethodId( + r'', + r'()V', + ); + + static final _$_clinit_ = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallStaticVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `static void ()` + static void $_clinit_() { + _$_clinit_(_class.reference.pointer, _id_$_clinit_ as jni$_.JMethodIDPtr) + .check(); + } } final class $Fields$Nested$NullableType$ extends jni$_.JType { @@ -2651,6 +2937,29 @@ class Fields extends jni$_.JObject { _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr) .reference); } + + static final _id_$_clinit_ = _class.staticMethodId( + r'', + r'()V', + ); + + static final _$_clinit_ = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallStaticVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `static void ()` + static void $_clinit_() { + _$_clinit_(_class.reference.pointer, _id_$_clinit_ as jni$_.JMethodIDPtr) + .check(); + } } final class $Fields$NullableType$ extends jni$_.JType { @@ -2781,6 +3090,29 @@ class C2 extends jni$_.JObject { _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr) .reference); } + + static final _id_$_clinit_ = _class.staticMethodId( + r'', + r'()V', + ); + + static final _$_clinit_ = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallStaticVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `static void ()` + static void $_clinit_() { + _$_clinit_(_class.reference.pointer, _id_$_clinit_ as jni$_.JMethodIDPtr) + .check(); + } } final class $C2$NullableType$ extends jni$_.JType { @@ -3103,12 +3435,12 @@ class Colors$RGB extends jni$_.JObject { .boolean; } - static final _id_hashCode$1 = _class.instanceMethodId( + static final _id_hashCode = _class.instanceMethodId( r'hashCode', r'()I', ); - static final _hashCode$1 = jni$_.ProtectedJniExtensions.lookup< + static final _hashCode = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -3121,8 +3453,8 @@ class Colors$RGB extends jni$_.JObject { )>(); /// from: `public int hashCode()` - int hashCode$1() { - return _hashCode$1(reference.pointer, _id_hashCode$1 as jni$_.JMethodIDPtr) + int hashCode() { + return _hashCode(reference.pointer, _id_hashCode as jni$_.JMethodIDPtr) .integer; } } @@ -3309,6 +3641,38 @@ class Colors extends jni$_.JObject { .object(const $Colors$NullableType$()); } + static final _id_new$ = _class.constructorId( + r'(Ljava/lang/String;II)V', + ); + + static final _new$ = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32, + jni$_.Int32 + )>)>>('globalEnv_NewObject') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int, int)>(); + + /// from: `private void (java.lang.String string, int i, int i1)` + /// The returned object must be released after use, by calling the [release] method. + factory Colors( + jni$_.JString? string, + int i, + int i1, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + return Colors.fromReference(_new$(_class.reference.pointer, + _id_new$ as jni$_.JMethodIDPtr, _$string.pointer, i, i1) + .reference); + } + static final _id_toRGB = _class.instanceMethodId( r'toRGB', r'()Lcom/github/dart_lang/jnigen/enums/Colors$RGB;', @@ -3332,6 +3696,29 @@ class Colors extends jni$_.JObject { return _toRGB(reference.pointer, _id_toRGB as jni$_.JMethodIDPtr) .object(const $Colors$RGB$NullableType$()); } + + static final _id_$_clinit_ = _class.staticMethodId( + r'', + r'()V', + ); + + static final _$_clinit_ = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallStaticVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `static void ()` + static void $_clinit_() { + _$_clinit_(_class.reference.pointer, _id_$_clinit_ as jni$_.JMethodIDPtr) + .check(); + } } final class $Colors$NullableType$ extends jni$_.JType { @@ -3715,30 +4102,30 @@ class GrandParent$Parent$Child< /// from: `public void (com.github.dart_lang.jnigen.generics.GrandParent$Parent $outerClass, U object)` /// The returned object must be released after use, by calling the [release] method. factory GrandParent$Parent$Child( - GrandParent$Parent<$T?, $S?> $outerClass, + GrandParent$Parent<$T?, $S?> $$outerClass, $U? object, { jni$_.JType<$T>? T, jni$_.JType<$S>? S, required jni$_.JType<$U> U, }) { T ??= jni$_.lowestCommonSuperType([ - ($outerClass.$type + ($$outerClass.$type as $GrandParent$Parent$Type$) .T, ]) as jni$_.JType<$T>; S ??= jni$_.lowestCommonSuperType([ - ($outerClass.$type + ($$outerClass.$type as $GrandParent$Parent$Type$) .S, ]) as jni$_.JType<$S>; - final _$$outerClass = $outerClass.reference; + final _$$$outerClass = $$outerClass.reference; final _$object = object?.reference ?? jni$_.jNullReference; return GrandParent$Parent$Child<$T, $S, $U>.fromReference( T, S, U, _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr, - _$$outerClass.pointer, _$object.pointer) + _$$$outerClass.pointer, _$object.pointer) .reference); } } @@ -3965,21 +4352,21 @@ class GrandParent$Parent<$T extends jni$_.JObject?, $S extends jni$_.JObject?> /// from: `public void (com.github.dart_lang.jnigen.generics.GrandParent $outerClass, S object)` /// The returned object must be released after use, by calling the [release] method. factory GrandParent$Parent( - GrandParent<$T?> $outerClass, + GrandParent<$T?> $$outerClass, $S? object, { jni$_.JType<$T>? T, required jni$_.JType<$S> S, }) { T ??= jni$_.lowestCommonSuperType([ - ($outerClass.$type as $GrandParent$Type$).T, + ($$outerClass.$type as $GrandParent$Type$).T, ]) as jni$_.JType<$T>; - final _$$outerClass = $outerClass.reference; + final _$$$outerClass = $$outerClass.reference; final _$object = object?.reference ?? jni$_.jNullReference; return GrandParent$Parent<$T, $S>.fromReference( T, S, _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr, - _$$outerClass.pointer, _$object.pointer) + _$$$outerClass.pointer, _$object.pointer) .reference); } } @@ -4191,23 +4578,23 @@ class GrandParent$StaticParent$Child<$S extends jni$_.JObject?, /// from: `public void (com.github.dart_lang.jnigen.generics.GrandParent$StaticParent $outerClass, S object, U object1)` /// The returned object must be released after use, by calling the [release] method. factory GrandParent$StaticParent$Child( - GrandParent$StaticParent<$S?> $outerClass, + GrandParent$StaticParent<$S?> $$outerClass, $S? object, $U? object1, { jni$_.JType<$S>? S, required jni$_.JType<$U> U, }) { S ??= jni$_.lowestCommonSuperType([ - ($outerClass.$type as $GrandParent$StaticParent$Type$).S, + ($$outerClass.$type as $GrandParent$StaticParent$Type$).S, ]) as jni$_.JType<$S>; - final _$$outerClass = $outerClass.reference; + final _$$$outerClass = $$outerClass.reference; final _$object = object?.reference ?? jni$_.jNullReference; final _$object1 = object1?.reference ?? jni$_.jNullReference; return GrandParent$StaticParent$Child<$S, $U>.fromReference( S, U, _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr, - _$$outerClass.pointer, _$object.pointer, _$object1.pointer) + _$$$outerClass.pointer, _$object.pointer, _$object1.pointer) .reference); } } @@ -4910,26 +5297,26 @@ class MyMap$MyEntry<$K extends jni$_.JObject?, $V extends jni$_.JObject?> /// from: `public void (com.github.dart_lang.jnigen.generics.MyMap $outerClass, K object, V object1)` /// The returned object must be released after use, by calling the [release] method. factory MyMap$MyEntry( - MyMap<$K?, $V?> $outerClass, + MyMap<$K?, $V?> $$outerClass, $K? object, $V? object1, { jni$_.JType<$K>? K, jni$_.JType<$V>? V, }) { K ??= jni$_.lowestCommonSuperType([ - ($outerClass.$type as $MyMap$Type$).K, + ($$outerClass.$type as $MyMap$Type$).K, ]) as jni$_.JType<$K>; V ??= jni$_.lowestCommonSuperType([ - ($outerClass.$type as $MyMap$Type$).V, + ($$outerClass.$type as $MyMap$Type$).V, ]) as jni$_.JType<$V>; - final _$$outerClass = $outerClass.reference; + final _$$$outerClass = $$outerClass.reference; final _$object = object?.reference ?? jni$_.jNullReference; final _$object1 = object1?.reference ?? jni$_.jNullReference; return MyMap$MyEntry<$K, $V>.fromReference( K, V, _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr, - _$$outerClass.pointer, _$object.pointer, _$object1.pointer) + _$$$outerClass.pointer, _$object.pointer, _$object1.pointer) .reference); } } @@ -5087,6 +5474,23 @@ class MyMap<$K extends jni$_.JObject?, $V extends jni$_.JObject?> ); } + static final _id_map = _class.instanceFieldId( + r'map', + r'Ljava/util/Map;', + ); + + /// from: `private java.util.Map map` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JMap<$K?, $V?>? get map => _id_map.get(this, + jni$_.$JMap$NullableType$<$K?, $V?>(K.nullableType, V.nullableType)); + + /// from: `private java.util.Map map` + /// The returned object must be released after use, by calling the [release] method. + set map(jni$_.JMap<$K?, $V?>? value) => _id_map.set( + this, + jni$_.$JMap$NullableType$<$K?, $V?>(K.nullableType, V.nullableType), + value); + static final _id_new$ = _class.constructorId( r'()V', ); @@ -5345,6 +5749,21 @@ class MyStack<$T extends jni$_.JObject?> extends jni$_.JObject { ); } + static final _id_stack = _class.instanceFieldId( + r'stack', + r'Ljava/util/Stack;', + ); + + /// from: `private java.util.Stack stack` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? get stack => + _id_stack.get(this, const jni$_.$JObject$NullableType$()); + + /// from: `private java.util.Stack stack` + /// The returned object must be released after use, by calling the [release] method. + set stack(jni$_.JObject? value) => + _id_stack.set(this, const jni$_.$JObject$NullableType$(), value); + static final _id_new$ = _class.constructorId( r'()V', ); @@ -5749,6 +6168,95 @@ class StringKeyedMap<$V extends jni$_.JObject?> _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr) .reference); } + + static final _id_get = _class.instanceMethodId( + r'get', + r'(Ljava/lang/String;)Ljava/lang/Object;', + ); + + static final _get = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public V get(java.lang.String object)` + /// The returned object must be released after use, by calling the [release] method. + $V? get( + jni$_.JString? object, + ) { + final _$object = object?.reference ?? jni$_.jNullReference; + return _get( + reference.pointer, _id_get as jni$_.JMethodIDPtr, _$object.pointer) + .object<$V?>(V.nullableType); + } + + static final _id_put = _class.instanceMethodId( + r'put', + r'(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;', + ); + + static final _put = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public V put(java.lang.String object, V object1)` + /// The returned object must be released after use, by calling the [release] method. + $V? put( + jni$_.JString? object, + $V? object1, + ) { + final _$object = object?.reference ?? jni$_.jNullReference; + final _$object1 = object1?.reference ?? jni$_.jNullReference; + return _put(reference.pointer, _id_put as jni$_.JMethodIDPtr, + _$object.pointer, _$object1.pointer) + .object<$V?>(V.nullableType); + } + + static final _id_entryStack = _class.instanceMethodId( + r'entryStack', + r'()Lcom/github/dart_lang/jnigen/generics/MyStack;', + ); + + static final _entryStack = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public com.github.dart_lang.jnigen.generics.MyStack> entryStack()` + /// The returned object must be released after use, by calling the [release] method. + MyStack?>? entryStack() { + return _entryStack(reference.pointer, _id_entryStack as jni$_.JMethodIDPtr) + .object?>?>( + $MyStack$NullableType$?>( + $MyMap$MyEntry$NullableType$( + const jni$_.$JString$NullableType$(), V.nullableType))); + } } final class $StringKeyedMap$NullableType$<$V extends jni$_.JObject?> @@ -5890,6 +6398,97 @@ class StringMap extends StringKeyedMap { _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr) .reference); } + + static final _id_get = _class.instanceMethodId( + r'get', + r'(Ljava/lang/String;)Ljava/lang/String;', + ); + + static final _get = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public java.lang.String get(java.lang.String object)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? get( + jni$_.JString? object, + ) { + final _$object = object?.reference ?? jni$_.jNullReference; + return _get( + reference.pointer, _id_get as jni$_.JMethodIDPtr, _$object.pointer) + .object(const jni$_.$JString$NullableType$()); + } + + static final _id_put = _class.instanceMethodId( + r'put', + r'(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;', + ); + + static final _put = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public java.lang.String put(java.lang.String object, java.lang.String object1)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? put( + jni$_.JString? object, + jni$_.JString? object1, + ) { + final _$object = object?.reference ?? jni$_.jNullReference; + final _$object1 = object1?.reference ?? jni$_.jNullReference; + return _put(reference.pointer, _id_put as jni$_.JMethodIDPtr, + _$object.pointer, _$object1.pointer) + .object(const jni$_.$JString$NullableType$()); + } + + static final _id_entryStack = _class.instanceMethodId( + r'entryStack', + r'()Lcom/github/dart_lang/jnigen/generics/MyStack;', + ); + + static final _entryStack = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public com.github.dart_lang.jnigen.generics.MyStack> entryStack()` + /// The returned object must be released after use, by calling the [release] method. + MyStack?>? entryStack() { + return _entryStack(reference.pointer, _id_entryStack as jni$_.JMethodIDPtr) + .object?>?>( + const $MyStack$NullableType$< + MyMap$MyEntry?>( + $MyMap$MyEntry$NullableType$( + jni$_.$JString$NullableType$(), + jni$_.$JString$NullableType$()))); + } } final class $StringMap$NullableType$ extends jni$_.JType { @@ -5980,37 +6579,108 @@ class StringStack extends MyStack { ) : $type = type, super.fromReference(const jni$_.$JString$NullableType$(), reference); - static final _class = - jni$_.JClass.forName(r'com/github/dart_lang/jnigen/generics/StringStack'); + static final _class = + jni$_.JClass.forName(r'com/github/dart_lang/jnigen/generics/StringStack'); + + /// The type which includes information such as the signature of this class. + static const jni$_.JType nullableType = + $StringStack$NullableType$(); + + /// The type which includes information such as the signature of this class. + static const jni$_.JType type = $StringStack$Type$(); + static final _id_new$ = _class.constructorId( + r'()V', + ); + + static final _new$ = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_NewObject') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public void ()` + /// The returned object must be released after use, by calling the [release] method. + factory StringStack() { + return StringStack.fromReference( + _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr) + .reference); + } + + static final _id_push = _class.instanceMethodId( + r'push', + r'(Ljava/lang/String;)V', + ); + + static final _push = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void push(java.lang.String object)` + void push( + jni$_.JString? object, + ) { + final _$object = object?.reference ?? jni$_.jNullReference; + _push(reference.pointer, _id_push as jni$_.JMethodIDPtr, _$object.pointer) + .check(); + } + + static final _id_pop = _class.instanceMethodId( + r'pop', + r'()Ljava/lang/String;', + ); + + static final _pop = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// The type which includes information such as the signature of this class. - static const jni$_.JType nullableType = - $StringStack$NullableType$(); + /// from: `public java.lang.String pop()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? pop() { + return _pop(reference.pointer, _id_pop as jni$_.JMethodIDPtr) + .object(const jni$_.$JString$NullableType$()); + } - /// The type which includes information such as the signature of this class. - static const jni$_.JType type = $StringStack$Type$(); - static final _id_new$ = _class.constructorId( - r'()V', + static final _id_size = _class.instanceMethodId( + r'size', + r'()I', ); - static final _new$ = jni$_.ProtectedJniExtensions.lookup< + static final _size = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_NewObject') + )>>('globalEnv_CallIntMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public void ()` - /// The returned object must be released after use, by calling the [release] method. - factory StringStack() { - return StringStack.fromReference( - _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr) - .reference); + /// from: `public int size()` + int size() { + return _size(reference.pointer, _id_size as jni$_.JMethodIDPtr).integer; } } @@ -6156,6 +6826,95 @@ class StringValuedMap<$K extends jni$_.JObject?> _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr) .reference); } + + static final _id_get = _class.instanceMethodId( + r'get', + r'(Ljava/lang/Object;)Ljava/lang/String;', + ); + + static final _get = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public java.lang.String get(K object)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? get( + $K? object, + ) { + final _$object = object?.reference ?? jni$_.jNullReference; + return _get( + reference.pointer, _id_get as jni$_.JMethodIDPtr, _$object.pointer) + .object(const jni$_.$JString$NullableType$()); + } + + static final _id_put = _class.instanceMethodId( + r'put', + r'(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String;', + ); + + static final _put = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public java.lang.String put(K object, java.lang.String object1)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? put( + $K? object, + jni$_.JString? object1, + ) { + final _$object = object?.reference ?? jni$_.jNullReference; + final _$object1 = object1?.reference ?? jni$_.jNullReference; + return _put(reference.pointer, _id_put as jni$_.JMethodIDPtr, + _$object.pointer, _$object1.pointer) + .object(const jni$_.$JString$NullableType$()); + } + + static final _id_entryStack = _class.instanceMethodId( + r'entryStack', + r'()Lcom/github/dart_lang/jnigen/generics/MyStack;', + ); + + static final _entryStack = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public com.github.dart_lang.jnigen.generics.MyStack> entryStack()` + /// The returned object must be released after use, by calling the [release] method. + MyStack?>? entryStack() { + return _entryStack(reference.pointer, _id_entryStack as jni$_.JMethodIDPtr) + .object?>?>( + $MyStack$NullableType$?>( + $MyMap$MyEntry$NullableType$<$K?, jni$_.JString?>( + K.nullableType, const jni$_.$JString$NullableType$()))); + } } final class $StringValuedMap$NullableType$<$K extends jni$_.JObject?> @@ -7031,7 +7790,7 @@ class InheritedFromMyInterface extends jni$_.JObject { .toPointer() ?? jni$_.nullptr; } - if ($d == r'varCallback(Ljava/lang/String;)Ljava/lang/String;') { + if ($d == r'varCallback(Ljava/lang/Object;)Ljava/lang/Object;') { final $r = _$impls[$p]!.varCallback( $a![0]?.as(const jni$_.$JString$Type$(), releaseOriginal: true), ); @@ -8363,6 +9122,16 @@ class MyRunnableRunner extends jni$_.JObject { /// The type which includes information such as the signature of this class. static const jni$_.JType type = $MyRunnableRunner$Type$(); + static final _id_runnable = _class.instanceFieldId( + r'runnable', + r'Lcom/github/dart_lang/jnigen/interfaces/MyRunnable;', + ); + + /// from: `final com.github.dart_lang.jnigen.interfaces.MyRunnable runnable` + /// The returned object must be released after use, by calling the [release] method. + MyRunnable? get runnable => + _id_runnable.get(this, const $MyRunnable$NullableType$()); + static final _id_error = _class.instanceFieldId( r'error', r'Ljava/lang/Throwable;', @@ -9798,6 +10567,30 @@ class DerivedInterface extends jni$_.JObject { .object(const jni$_.$JString$NullableType$()); } + static final _id_foo = _class.instanceMethodId( + r'foo', + r'()Ljava/lang/Object;', + ); + + static final _foo = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `synthetic public bridge java.lang.Object foo()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? foo() { + return _foo(reference.pointer, _id_foo as jni$_.JMethodIDPtr) + .object(const jni$_.$JObject$NullableType$()); + } + /// Maps a specific port to the implemented interface. static final core$_.Map _$impls = {}; static jni$_.JObjectPtr _$invoke( @@ -9836,6 +10629,14 @@ class DerivedInterface extends jni$_.JObject { .toPointer() ?? jni$_.nullptr; } + if ($d == r'foo()Ljava/lang/Object;') { + final $r = _$impls[$p]!.foo(); + return ($r as jni$_.JObject?) + ?.as(const jni$_.$JObject$Type$()) + .reference + .toPointer() ?? + jni$_.nullptr; + } } catch (e) { return jni$_.ProtectedJniExtensions.newDartException(e); } @@ -9881,21 +10682,30 @@ class DerivedInterface extends jni$_.JObject { abstract base mixin class $DerivedInterface { factory $DerivedInterface({ required jni$_.JString? Function() foo, + required jni$_.JObject? Function() foo, }) = _$DerivedInterface; jni$_.JString? foo(); + jni$_.JObject? foo(); } final class _$DerivedInterface with $DerivedInterface { _$DerivedInterface({ required jni$_.JString? Function() foo, - }) : _foo = foo; + required jni$_.JObject? Function() foo, + }) : _foo = foo, + _foo = foo; final jni$_.JString? Function() _foo; + final jni$_.JObject? Function() _foo; jni$_.JString? foo() { return _foo(); } + + jni$_.JObject? foo() { + return _foo(); + } } final class $DerivedInterface$NullableType$ @@ -10383,7 +11193,7 @@ class Annotated$Nested<$T extends jni$_.JObject?, $U extends jni$_.JObject, /// from: `public void (com.github.dart_lang.jnigen.annotations.Annotated $outerClass, V object)` /// The returned object must be released after use, by calling the [release] method. factory Annotated$Nested( - Annotated<$T?, $U, $W> $outerClass, + Annotated<$T?, $U, $W> $$outerClass, $V? object, { jni$_.JType<$T>? T, jni$_.JType<$U>? U, @@ -10391,21 +11201,21 @@ class Annotated$Nested<$T extends jni$_.JObject?, $U extends jni$_.JObject, required jni$_.JType<$V> V, }) { T ??= jni$_.lowestCommonSuperType([ - ($outerClass.$type as $Annotated$Type$) .T, ]) as jni$_.JType<$T>; U ??= jni$_.lowestCommonSuperType([ - ($outerClass.$type as $Annotated$Type$) .U, ]) as jni$_.JType<$U>; W ??= jni$_.lowestCommonSuperType([ - ($outerClass.$type as $Annotated$Type$) .W, ]) as jni$_.JType<$W>; - final _$$outerClass = $outerClass.reference; + final _$$$outerClass = $$outerClass.reference; final _$object = object?.reference ?? jni$_.jNullReference; return Annotated$Nested<$T, $U, $W, $V>.fromReference( T, @@ -10413,7 +11223,7 @@ class Annotated$Nested<$T extends jni$_.JObject?, $U extends jni$_.JObject, W, V, _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr, - _$$outerClass.pointer, _$object.pointer) + _$$$outerClass.pointer, _$object.pointer) .reference); } } @@ -12589,6 +13399,57 @@ class JsonSerializable$Case extends jni$_.JObject { .object( const $JsonSerializable$Case$NullableType$()); } + + static final _id_new$ = _class.constructorId( + r'(Ljava/lang/String;I)V', + ); + + static final _new$ = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_ + .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( + 'globalEnv_NewObject') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); + + /// from: `private void (java.lang.String string, int i)` + /// The returned object must be released after use, by calling the [release] method. + factory JsonSerializable$Case( + jni$_.JString? string, + int i, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + return JsonSerializable$Case.fromReference(_new$(_class.reference.pointer, + _id_new$ as jni$_.JMethodIDPtr, _$string.pointer, i) + .reference); + } + + static final _id_$_clinit_ = _class.staticMethodId( + r'', + r'()V', + ); + + static final _$_clinit_ = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallStaticVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `static void ()` + static void $_clinit_() { + _$_clinit_(_class.reference.pointer, _id_$_clinit_ as jni$_.JMethodIDPtr) + .check(); + } } final class $JsonSerializable$Case$NullableType$ @@ -13894,6 +14755,56 @@ class R693$Child extends R693 { _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr) .reference); } + + static final _id_foo$1 = _class.instanceMethodId( + r'foo', + r'()Lcom/github/dart_lang/jnigen/regressions/R693$Child;', + ); + + static final _foo$1 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `com.github.dart_lang.jnigen.regressions.R693$Child foo()` + /// The returned object must be released after use, by calling the [release] method. + R693$Child? foo$1() { + return _foo$1(reference.pointer, _id_foo$1 as jni$_.JMethodIDPtr) + .object(const $R693$Child$NullableType$()); + } + + static final _id_foo = _class.instanceMethodId( + r'foo', + r'()Lcom/github/dart_lang/jnigen/regressions/R693;', + ); + + static final _foo = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `synthetic bridge com.github.dart_lang.jnigen.regressions.R693 foo()` + /// The returned object must be released after use, by calling the [release] method. + R693? foo() { + return _foo(reference.pointer, _id_foo as jni$_.JMethodIDPtr) + .object?>( + const $R693$NullableType$( + jni$_.$JObject$NullableType$())); + } } final class $R693$Child$NullableType$ extends jni$_.JType { @@ -14037,6 +14948,30 @@ class R693<$T extends jni$_.JObject?> extends jni$_.JObject { _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr) .reference); } + + static final _id_foo = _class.instanceMethodId( + r'foo', + r'()Lcom/github/dart_lang/jnigen/regressions/R693;', + ); + + static final _foo = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `T foo()` + /// The returned object must be released after use, by calling the [release] method. + $T? foo() { + return _foo(reference.pointer, _id_foo as jni$_.JMethodIDPtr) + .object<$T?>(T.nullableType); + } } final class $R693$NullableType$<$T extends jni$_.JObject?> diff --git a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/inheritance/BaseGenericInterface.java b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/inheritance/BaseGenericInterface.java index 6cfce54d60..9b3531f8e7 100644 --- a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/inheritance/BaseGenericInterface.java +++ b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/inheritance/BaseGenericInterface.java @@ -1,3 +1,7 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + package com.github.dart_lang.jnigen.inheritance; public interface BaseGenericInterface { diff --git a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/inheritance/BaseInterface.java b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/inheritance/BaseInterface.java index b035dddb91..1269d07b03 100644 --- a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/inheritance/BaseInterface.java +++ b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/inheritance/BaseInterface.java @@ -1,3 +1,7 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + package com.github.dart_lang.jnigen.inheritance; public interface BaseInterface { diff --git a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/inheritance/DerivedInterface.java b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/inheritance/DerivedInterface.java index 4afebd50ea..bfee1fd8f3 100644 --- a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/inheritance/DerivedInterface.java +++ b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/inheritance/DerivedInterface.java @@ -1,3 +1,7 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + package com.github.dart_lang.jnigen.inheritance; public interface DerivedInterface extends BaseGenericInterface, BaseInterface { diff --git a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/interfaces/InheritedFromMyInterface.java b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/interfaces/InheritedFromMyInterface.java index a8bbe2e394..80c4831b24 100644 --- a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/interfaces/InheritedFromMyInterface.java +++ b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/interfaces/InheritedFromMyInterface.java @@ -1,3 +1,7 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + package com.github.dart_lang.jnigen.interfaces; public interface InheritedFromMyInterface extends MyInterface {} diff --git a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/interfaces/InheritedFromMyRunnable.java b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/interfaces/InheritedFromMyRunnable.java index 81cc74f73d..31b673277e 100644 --- a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/interfaces/InheritedFromMyRunnable.java +++ b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/interfaces/InheritedFromMyRunnable.java @@ -1,3 +1,7 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + package com.github.dart_lang.jnigen.interfaces; public interface InheritedFromMyRunnable extends MyRunnable {} diff --git a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/Duck.java b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/Duck.java new file mode 100644 index 0000000000..6433a67a16 --- /dev/null +++ b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/Duck.java @@ -0,0 +1,7 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package com.github.dart_lang.jnigen.overrides; + +public class Duck {} diff --git a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/Ducking.java b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/Ducking.java new file mode 100644 index 0000000000..0388d55fa4 --- /dev/null +++ b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/Ducking.java @@ -0,0 +1,9 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package com.github.dart_lang.jnigen.overrides; + +public interface Ducking { + void duck(); +} diff --git a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/DuckingPlayer.java b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/DuckingPlayer.java new file mode 100644 index 0000000000..6e9106cf08 --- /dev/null +++ b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/DuckingPlayer.java @@ -0,0 +1,7 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package com.github.dart_lang.jnigen.overrides; + +public class DuckingPlayer extends Player implements Ducking, JustAChillDuck {} diff --git a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/JustAChillDuck.java b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/JustAChillDuck.java new file mode 100644 index 0000000000..24a66b44a6 --- /dev/null +++ b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/JustAChillDuck.java @@ -0,0 +1,9 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package com.github.dart_lang.jnigen.overrides; + +public interface JustAChillDuck { + void duck(); +} diff --git a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/Player.java b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/Player.java new file mode 100644 index 0000000000..c46795283f --- /dev/null +++ b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/overrides/Player.java @@ -0,0 +1,13 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +package com.github.dart_lang.jnigen.overrides; + +public class Player { + // Player's personal duck! + public Duck duck; + + // Lower your head! + public void duck() {} +} diff --git a/pkgs/jnigen/test/user_visitor_test.dart b/pkgs/jnigen/test/user_visitor_test.dart deleted file mode 100644 index 1a621665d9..0000000000 --- a/pkgs/jnigen/test/user_visitor_test.dart +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:jnigen/jnigen.dart' as jnigen; -import 'package:jnigen/src/bindings/linker.dart'; -import 'package:jnigen/src/bindings/renamer.dart'; -import 'package:jnigen/src/elements/elements.dart' as ast; -import 'package:jnigen/src/elements/j_elements.dart'; -import 'package:test/test.dart'; - -extension on Iterable { - List get isExcludedValues => - map((c) => c.userDefinedIsExcluded).toList(); -} - -extension on Iterable { - List get isExcludedValues => map((c) => c.isExcluded).toList(); -} - -extension on Iterable { - List get finalNames => map((m) => m.finalName).toList(); -} - -extension on Iterable { - List get finalNames => map((p) => p.finalName).toList(); -} - -extension on Iterable { - List get finalNames => map((f) => f.finalName).toList(); -} - -// This is customizable by the user -class UserExcluder extends Visitor { - @override - void visitClass(ClassDecl c) { - if (c.binaryName.contains('y')) { - c.isExcluded = true; - } - } - - @override - void visitMethod(Method method) { - if (method.name == 'Bar') { - method.isExcluded = true; - } - } - - @override - void visitField(Field field) { - if (field.name == 'Bar') { - field.isExcluded = true; - } - } -} - -// This is customizable by the user -class UserRenamer extends Visitor { - @override - void visitClass(ClassDecl c) { - if (c.originalName.contains('Foo')) { - c.name = c.originalName.replaceAll('Foo', 'Bar'); - } - } - - @override - void visitMethod(Method method) { - if (method.originalName.contains('Foo')) { - method.name = method.originalName.replaceAll('Foo', 'Bar'); - } - if (method.isConstructor) { - method.name = 'constructor'; - } - } - - @override - void visitField(Field field) { - if (field.originalName.contains('Foo')) { - field.name = field.originalName.replaceAll('Foo', 'Bar'); - } - } - - @override - void visitParam(Param parameter) { - if (parameter.originalName.contains('Foo')) { - parameter.name = parameter.originalName.replaceAll('Foo', 'Bar'); - } - } -} - -Future rename(ast.Classes classes) async { - final config = jnigen.Config( - outputConfig: jnigen.OutputConfig( - dartConfig: jnigen.DartCodeOutputConfig( - path: Uri.file('test.dart'), - structure: jnigen.OutputStructure.singleFile, - ), - ), - classes: []); - await classes.accept(Linker(config)); - classes.accept(Renamer(config)); -} - -void main() { - test('Exclude something using the user excluder, Simple AST', () async { - final classes = ast.Classes({ - 'Foo': ast.ClassDecl( - binaryName: 'Foo', - declKind: ast.DeclKind.classKind, - superclass: ast.DeclaredType.object, - methods: [ - ast.Method(name: 'foo', returnType: ast.DeclaredType.object), - ast.Method(name: 'Bar', returnType: ast.DeclaredType.object), - ast.Method(name: 'foo1', returnType: ast.DeclaredType.object), - ast.Method(name: 'Bar', returnType: ast.DeclaredType.object), - ], - fields: [ - ast.Field(name: 'foo', type: ast.DeclaredType.object), - ast.Field(name: 'Bar', type: ast.DeclaredType.object), - ast.Field(name: 'foo1', type: ast.DeclaredType.object), - ast.Field(name: 'Bar', type: ast.DeclaredType.object), - ], - ), - 'y.Foo': ast.ClassDecl( - binaryName: 'y.Foo', - declKind: ast.DeclKind.classKind, - superclass: ast.DeclaredType.object, - methods: [ - ast.Method(name: 'foo', returnType: ast.DeclaredType.object), - ast.Method(name: 'Bar', returnType: ast.DeclaredType.object), - ], - fields: [ - ast.Field(name: 'foo', type: ast.DeclaredType.object), - ast.Field(name: 'Bar', type: ast.DeclaredType.object), - ]), - }); - - final simpleClasses = Classes(classes); - simpleClasses.accept(UserExcluder()); - - expect(classes.decls['y.Foo']?.isExcluded, true); - expect(classes.decls['Foo']?.isExcluded, false); - - expect(classes.decls['Foo']?.fields.isExcludedValues, - [false, true, false, true]); - expect(classes.decls['Foo']?.methods.isExcludedValues, - [false, true, false, true]); - }); - - test('Rename classes, fields, methods and params using the user renamer', - () async { - final classes = ast.Classes({ - 'Foo': ast.ClassDecl( - binaryName: 'Foo', - declKind: ast.DeclKind.classKind, - superclass: ast.DeclaredType.object, - methods: [ - ast.Method(name: 'Foo', returnType: ast.DeclaredType.object), - ast.Method(name: 'Foo', returnType: ast.DeclaredType.object), - ast.Method(name: 'Foo1', returnType: ast.DeclaredType.object), - ast.Method(name: 'Foo1', returnType: ast.DeclaredType.object), - ], - fields: [ - ast.Field(name: 'Foo', type: ast.DeclaredType.object), - ast.Field(name: 'Foo', type: ast.DeclaredType.object), - ast.Field(name: 'Foo1', type: ast.DeclaredType.object), - ast.Field(name: 'Foo1', type: ast.DeclaredType.object), - ], - ), - 'y.Foo': ast.ClassDecl( - binaryName: 'y.Foo', - declKind: ast.DeclKind.classKind, - superclass: ast.DeclaredType.object, - methods: [ - ast.Method(name: 'Foo', returnType: ast.DeclaredType.object, params: [ - ast.Param(name: 'Foo', type: ast.DeclaredType.object), - ast.Param(name: 'Foo1', type: ast.DeclaredType.object), - ]), - ast.Method(name: '', returnType: ast.DeclaredType.object) - ], - ), - }); - - final simpleClasses = Classes(classes); - simpleClasses.accept(UserRenamer()); - - await rename(classes); - - expect(classes.decls['Foo']?.finalName, 'Bar'); - expect(classes.decls['y.Foo']?.finalName, r'Bar$1'); - - expect(classes.decls['Foo']?.fields.finalNames, - ['Bar', r'Bar$1', 'Bar1', r'Bar1$1']); - - expect(classes.decls['Foo']?.methods.finalNames, - [r'Bar$2', r'Bar$3', r'Bar1$2', r'Bar1$3']); - - expect(classes.decls['y.Foo']?.methods.finalNames, [r'Bar', 'constructor']); - - expect(classes.decls['y.Foo']?.methods.first.params.finalNames, - ['Bar', 'Bar1']); - }); -}