Skip to content

Commit 4d81ce6

Browse files
Rename top-level Kotlin functions and properties correctly (#1807)
Closes #1658
1 parent 49ce690 commit 4d81ce6

File tree

4 files changed

+99
-4
lines changed

4 files changed

+99
-4
lines changed

pkgs/jnigen/lib/src/bindings/renamer.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class Renamer implements Visitor<Classes, void> {
155155
class _ClassRenamer implements Visitor<ClassDecl, void> {
156156
final Config config;
157157
final Set<ClassDecl> renamed;
158-
final Map<String, int> classNameCounts = {};
158+
final Map<String, int> topLevelNameCounts = {};
159159
final Map<ClassDecl, Map<String, int>> nameCounts = {};
160160

161161
_ClassRenamer(
@@ -192,7 +192,7 @@ class _ClassRenamer implements Visitor<ClassDecl, void> {
192192
final uniquifyName =
193193
config.outputConfig.dartConfig.structure == OutputStructure.singleFile;
194194
node.finalName = uniquifyName
195-
? _renameConflict(classNameCounts, className, _ElementKind.klass)
195+
? _renameConflict(topLevelNameCounts, className, _ElementKind.klass)
196196
: className;
197197
node.typeClassName = '\$${node.finalName}\$Type';
198198
node.nullableTypeClassName = '\$${node.finalName}\$NullableType';
@@ -201,14 +201,17 @@ class _ClassRenamer implements Visitor<ClassDecl, void> {
201201
// Rename fields before renaming methods. In case a method and a field have
202202
// identical names, the field will keep its original name and the
203203
// method will be renamed.
204-
final fieldRenamer = _FieldRenamer(config, nameCounts[node]!);
204+
final fieldRenamer = _FieldRenamer(
205+
config,
206+
uniquifyName && node.isTopLevel ? topLevelNameCounts : nameCounts[node]!,
207+
);
205208
for (final field in node.fields) {
206209
field.accept(fieldRenamer);
207210
}
208211

209212
final methodRenamer = _MethodRenamer(
210213
config,
211-
nameCounts[node]!,
214+
uniquifyName && node.isTopLevel ? topLevelNameCounts : nameCounts[node]!,
212215
);
213216
for (final method in node.methods) {
214217
method.accept(methodRenamer);

pkgs/jnigen/test/kotlin_test/bindings/kotlin.dart

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,3 +2396,77 @@ int topLevelSum(
23962396
_id_topLevelSum as jni$_.JMethodIDPtr, i, i1)
23972397
.integer;
23982398
}
2399+
2400+
final _TopLevelKt$1Class =
2401+
jni$_.JClass.forName(r'com/github/dart_lang/jnigen/subpackage/TopLevelKt');
2402+
2403+
final _id_getTopLevelField$1 = _TopLevelKt$1Class.staticMethodId(
2404+
r'getTopLevelField',
2405+
r'()I',
2406+
);
2407+
2408+
final _getTopLevelField$1 = jni$_.ProtectedJniExtensions.lookup<
2409+
jni$_.NativeFunction<
2410+
jni$_.JniResult Function(
2411+
jni$_.Pointer<jni$_.Void>,
2412+
jni$_.JMethodIDPtr,
2413+
)>>('globalEnv_CallStaticIntMethod')
2414+
.asFunction<
2415+
jni$_.JniResult Function(
2416+
jni$_.Pointer<jni$_.Void>,
2417+
jni$_.JMethodIDPtr,
2418+
)>();
2419+
2420+
/// from: `static public final int getTopLevelField()`
2421+
int getTopLevelField$1() {
2422+
return _getTopLevelField$1(_TopLevelKt$1Class.reference.pointer,
2423+
_id_getTopLevelField$1 as jni$_.JMethodIDPtr)
2424+
.integer;
2425+
}
2426+
2427+
final _id_setTopLevelField$1 = _TopLevelKt$1Class.staticMethodId(
2428+
r'setTopLevelField',
2429+
r'(I)V',
2430+
);
2431+
2432+
final _setTopLevelField$1 = jni$_.ProtectedJniExtensions.lookup<
2433+
jni$_.NativeFunction<
2434+
jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
2435+
jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Int32,)>)>>(
2436+
'globalEnv_CallStaticVoidMethod')
2437+
.asFunction<
2438+
jni$_.JThrowablePtr Function(
2439+
jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
2440+
2441+
/// from: `static public final void setTopLevelField(int i)`
2442+
void setTopLevelField$1(
2443+
int i,
2444+
) {
2445+
_setTopLevelField$1(_TopLevelKt$1Class.reference.pointer,
2446+
_id_setTopLevelField$1 as jni$_.JMethodIDPtr, i)
2447+
.check();
2448+
}
2449+
2450+
final _id_topLevel$1 = _TopLevelKt$1Class.staticMethodId(
2451+
r'topLevel',
2452+
r'()I',
2453+
);
2454+
2455+
final _topLevel$1 = jni$_.ProtectedJniExtensions.lookup<
2456+
jni$_.NativeFunction<
2457+
jni$_.JniResult Function(
2458+
jni$_.Pointer<jni$_.Void>,
2459+
jni$_.JMethodIDPtr,
2460+
)>>('globalEnv_CallStaticIntMethod')
2461+
.asFunction<
2462+
jni$_.JniResult Function(
2463+
jni$_.Pointer<jni$_.Void>,
2464+
jni$_.JMethodIDPtr,
2465+
)>();
2466+
2467+
/// from: `static public final int topLevel()`
2468+
int topLevel$1() {
2469+
return _topLevel$1(_TopLevelKt$1Class.reference.pointer,
2470+
_id_topLevel$1 as jni$_.JMethodIDPtr)
2471+
.integer;
2472+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
* for details. All rights reserved. Use of this source code is governed by a
3+
* BSD-style license that can be found in the LICENSE file.
4+
*/
5+
6+
package com.github.dart_lang.jnigen.subpackage
7+
8+
// The same property and function defined in `../TopLevel.kt` to test renaming.
9+
10+
var topLevelField: Int = 42
11+
12+
fun topLevel(): Int {
13+
return 42
14+
}

pkgs/jnigen/test/kotlin_test/runtime_test_registrant.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,14 @@ void registerTests(String groupName, TestRunnerCallback test) {
2424

2525
test('Top levels', () {
2626
expect(topLevel(), 42);
27+
expect(topLevel$1(), 42);
2728
expect(topLevelSum(10, 20), 30);
2829
expect(getTopLevelField(), 42);
30+
expect(getTopLevelField$1(), 42);
2931
setTopLevelField(30);
32+
setTopLevelField$1(30);
3033
expect(getTopLevelField(), 30);
34+
expect(getTopLevelField$1(), 30);
3135
});
3236

3337
test('Generics', () {

0 commit comments

Comments
 (0)