@@ -36,7 +36,6 @@ const _typeParamPrefix = '\$';
36
36
37
37
// Misc.
38
38
const _protectedExtension = 'ProtectedJniExtensions' ;
39
- const _classRef = '_class' ;
40
39
41
40
/// Used for C bindings.
42
41
const _selfPointer = 'reference.pointer' ;
@@ -266,8 +265,39 @@ class _ClassGenerator extends Visitor<ClassDecl, void> {
266
265
static const staticTypeGetter = 'type' ;
267
266
static const instanceTypeGetter = '\$ $staticTypeGetter ' ;
268
267
268
+ void generateFieldsAndMethods (ClassDecl node, String classRef) {
269
+ final fieldGenerator = _FieldGenerator (config, resolver, s,
270
+ isTopLevel: node.isTopLevel, classRef: classRef);
271
+ for (final field in node.fields) {
272
+ field.accept (fieldGenerator);
273
+ }
274
+ final methodGenerator = _MethodGenerator (config, resolver, s,
275
+ isTopLevel: node.isTopLevel, classRef: classRef);
276
+ for (final method in node.methods) {
277
+ method.accept (methodGenerator);
278
+ }
279
+ }
280
+
281
+ String writeClassRef (ClassDecl node) {
282
+ final internalName = node.internalName;
283
+ final modifier = node.isTopLevel ? '' : ' static ' ;
284
+ final classRef = node.isTopLevel ? '_${node .finalName }Class' : '_class' ;
285
+ s.write ('''
286
+ ${modifier }final $classRef = $_jni .JClass.forName(r"$internalName ");
287
+
288
+ ''' );
289
+ return classRef;
290
+ }
291
+
269
292
@override
270
293
void visit (ClassDecl node) {
294
+ if (node.isTopLevel) {
295
+ // If the class is top-level, only generate its methods and fields.
296
+ // Fields and Methods
297
+ final classRef = writeClassRef (node);
298
+ generateFieldsAndMethods (node, classRef);
299
+ return ;
300
+ }
271
301
// Docs.
272
302
s.write ('/// from: ${node .binaryName }\n ' );
273
303
node.javadoc? .accept (_DocGenerator (s, depth: 0 ));
@@ -326,11 +356,7 @@ class $name$typeParamsDef extends $superName {
326
356
327
357
''' );
328
358
329
- final internalName = node.internalName;
330
- s.write ('''
331
- static final $_classRef = $_jni .JClass.forName(r"$internalName ");
332
-
333
- ''' );
359
+ final classRef = writeClassRef (node);
334
360
335
361
// Static TypeClass getter.
336
362
s.writeln (
@@ -358,14 +384,7 @@ class $name$typeParamsDef extends $superName {
358
384
}
359
385
360
386
// Fields and Methods
361
- final fieldGenerator = _FieldGenerator (config, resolver, s);
362
- for (final field in node.fields) {
363
- field.accept (fieldGenerator);
364
- }
365
- final methodGenerator = _MethodGenerator (config, resolver, s);
366
- for (final method in node.methods) {
367
- method.accept (methodGenerator);
368
- }
387
+ generateFieldsAndMethods (node, classRef);
369
388
370
389
// Experimental: Interface implementation.
371
390
if (node.declKind == DeclKind .interfaceKind &&
@@ -889,16 +908,26 @@ class _FieldGenerator extends Visitor<Field, void> {
889
908
final Config config;
890
909
final Resolver resolver;
891
910
final StringSink s;
911
+ final bool isTopLevel;
912
+ final String classRef;
913
+
914
+ const _FieldGenerator (
915
+ this .config,
916
+ this .resolver,
917
+ this .s, {
918
+ required this .isTopLevel,
919
+ required this .classRef,
920
+ });
892
921
893
- const _FieldGenerator ( this .config, this .resolver, this .s) ;
922
+ String get modifier => isTopLevel ? '' : ' static ' ;
894
923
895
- void writeDartOnlyAccessor (Field node) {
924
+ void writeAccessor (Field node) {
896
925
final name = node.finalName;
897
926
final staticOrInstance = node.isStatic ? 'static' : 'instance' ;
898
927
final descriptor = node.type.descriptor;
899
928
s.write ('''
900
- static final _id_$name =
901
- $_classRef .${staticOrInstance }FieldId(
929
+ ${ modifier } final _id_$name =
930
+ $classRef .${staticOrInstance }FieldId(
902
931
r"${node .name }",
903
932
r"$descriptor ",
904
933
);
@@ -907,14 +936,14 @@ class _FieldGenerator extends Visitor<Field, void> {
907
936
908
937
String dartOnlyGetter (Field node) {
909
938
final name = node.finalName;
910
- final self = node.isStatic ? _classRef : _self;
939
+ final self = node.isStatic ? classRef : _self;
911
940
final type = node.type.accept (_TypeClassGenerator (resolver)).name;
912
941
return '_id_$name .get($self , $type )' ;
913
942
}
914
943
915
944
String dartOnlySetter (Field node) {
916
945
final name = node.finalName;
917
- final self = node.isStatic ? _classRef : _self;
946
+ final self = node.isStatic ? classRef : _self;
918
947
final type = node.type.accept (_TypeClassGenerator (resolver)).name;
919
948
return '_id_$name .set($self , $type , value)' ;
920
949
}
@@ -936,19 +965,19 @@ class _FieldGenerator extends Visitor<Field, void> {
936
965
final value = node.defaultValue! ;
937
966
if (value is num || value is bool ) {
938
967
writeDocs (node, writeReleaseInstructions: false );
939
- s.writeln (' static const $name = $value ;' );
968
+ s.writeln ('${ modifier } const $name = $value ;' );
940
969
return ;
941
970
}
942
971
}
943
972
944
973
// Accessors.
945
- writeDartOnlyAccessor (node);
974
+ writeAccessor (node);
946
975
947
976
// Getter docs.
948
977
writeDocs (node, writeReleaseInstructions: true );
949
978
950
979
final name = node.finalName;
951
- final ifStatic = node.isStatic ? 'static ' : '' ;
980
+ final ifStatic = node.isStatic && ! isTopLevel ? 'static ' : '' ;
952
981
final type = node.type.accept (_TypeGenerator (resolver));
953
982
s.write ('$ifStatic $type get $name => ' );
954
983
s.write (dartOnlyGetter (node));
@@ -994,10 +1023,20 @@ class _MethodGenerator extends Visitor<Method, void> {
994
1023
final Config config;
995
1024
final Resolver resolver;
996
1025
final StringSink s;
1026
+ final bool isTopLevel;
1027
+ final String classRef;
1028
+
1029
+ const _MethodGenerator (
1030
+ this .config,
1031
+ this .resolver,
1032
+ this .s, {
1033
+ required this .isTopLevel,
1034
+ required this .classRef,
1035
+ });
997
1036
998
- const _MethodGenerator ( this .config, this .resolver, this .s) ;
1037
+ String get modifier => isTopLevel ? '' : ' static ' ;
999
1038
1000
- void writeDartOnlyAccessor (Method node) {
1039
+ void writeAccessor (Method node) {
1001
1040
final name = node.finalName;
1002
1041
final kind = node.isCtor
1003
1042
? 'constructor'
@@ -1006,7 +1045,7 @@ class _MethodGenerator extends Visitor<Method, void> {
1006
1045
: 'instanceMethod' ;
1007
1046
final descriptor = node.descriptor;
1008
1047
s.write ('''
1009
- static final _id_$name = $_classRef .${kind }Id(
1048
+ ${ modifier } final _id_$name = $classRef .${kind }Id(
1010
1049
''' );
1011
1050
if (! node.isCtor) s.writeln (' r"${node .name }",' );
1012
1051
s.write ('''
@@ -1018,7 +1057,7 @@ class _MethodGenerator extends Visitor<Method, void> {
1018
1057
final methodName = node.accept (const _CallMethodName ());
1019
1058
s.write ('''
1020
1059
1021
- static final _$name = $_protectedExtension
1060
+ ${ modifier } final _$name = $_protectedExtension
1022
1061
.lookup<$_ffi .NativeFunction<$ffiSig >>("$methodName ")
1023
1062
.asFunction<$dartSig >();
1024
1063
''' );
@@ -1037,7 +1076,7 @@ class _MethodGenerator extends Visitor<Method, void> {
1037
1076
String dartOnlyCtor (Method node) {
1038
1077
final name = node.finalName;
1039
1078
final params = [
1040
- '$_classRef .reference.pointer' ,
1079
+ '$classRef .reference.pointer' ,
1041
1080
'_id_$name as $_jni .JMethodIDPtr' ,
1042
1081
...node.params.accept (const _ParamCall ()),
1043
1082
].join (', ' );
@@ -1057,7 +1096,7 @@ class _MethodGenerator extends Visitor<Method, void> {
1057
1096
String dartOnlyMethodCall (Method node) {
1058
1097
final name = node.finalName;
1059
1098
final params = [
1060
- node.isStatic ? '$_classRef .reference.pointer' : _selfPointer,
1099
+ node.isStatic ? '$classRef .reference.pointer' : _selfPointer,
1061
1100
'_id_$name as $_jni .JMethodIDPtr' ,
1062
1101
...node.params.accept (const _ParamCall ()),
1063
1102
].join (', ' );
@@ -1068,7 +1107,7 @@ class _MethodGenerator extends Visitor<Method, void> {
1068
1107
@override
1069
1108
void visit (Method node) {
1070
1109
// Accessors
1071
- writeDartOnlyAccessor (node);
1110
+ writeAccessor (node);
1072
1111
1073
1112
// Docs
1074
1113
s.write (' /// from: ' );
@@ -1145,7 +1184,7 @@ class _MethodGenerator extends Visitor<Method, void> {
1145
1184
final returnTypeClass = (node.asyncReturnType ?? node.returnType)
1146
1185
.accept (_TypeClassGenerator (resolver))
1147
1186
.name;
1148
- final ifStatic = node.isStatic ? 'static ' : '' ;
1187
+ final ifStatic = node.isStatic && ! isTopLevel ? 'static ' : '' ;
1149
1188
final defArgs = node.params.accept (_ParamDef (resolver)).toList ();
1150
1189
final typeClassDef = _encloseIfNotEmpty (
1151
1190
'{' ,
0 commit comments