Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename top-level Kotlin functions and properties correctly #1807

Merged
merged 5 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions pkgs/jnigen/lib/src/bindings/renamer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ class Renamer implements Visitor<Classes, void> {
class _ClassRenamer implements Visitor<ClassDecl, void> {
final Config config;
final Set<ClassDecl> renamed;
final Map<String, int> classNameCounts = {};
final Map<String, int> topLevelNameCounts = {};
final Map<ClassDecl, Map<String, int>> nameCounts = {};

_ClassRenamer(
Expand Down Expand Up @@ -192,7 +192,7 @@ class _ClassRenamer implements Visitor<ClassDecl, void> {
final uniquifyName =
config.outputConfig.dartConfig.structure == OutputStructure.singleFile;
node.finalName = uniquifyName
? _renameConflict(classNameCounts, className, _ElementKind.klass)
? _renameConflict(topLevelNameCounts, className, _ElementKind.klass)
: className;
node.typeClassName = '\$${node.finalName}\$Type';
node.nullableTypeClassName = '\$${node.finalName}\$NullableType';
Expand All @@ -201,14 +201,17 @@ class _ClassRenamer implements Visitor<ClassDecl, void> {
// 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, nameCounts[node]!);
final fieldRenamer = _FieldRenamer(
config,
uniquifyName && node.isTopLevel ? topLevelNameCounts : nameCounts[node]!,
);
for (final field in node.fields) {
field.accept(fieldRenamer);
}

final methodRenamer = _MethodRenamer(
config,
nameCounts[node]!,
uniquifyName && node.isTopLevel ? topLevelNameCounts : nameCounts[node]!,
);
for (final method in node.methods) {
method.accept(methodRenamer);
Expand Down
74 changes: 74 additions & 0 deletions pkgs/jnigen/test/kotlin_test/bindings/kotlin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2396,3 +2396,77 @@ int topLevelSum(
_id_topLevelSum as jni$_.JMethodIDPtr, i, i1)
.integer;
}

final _TopLevelKt$1Class =
jni$_.JClass.forName(r'com/github/dart_lang/jnigen/subpackage/TopLevelKt');

final _id_getTopLevelField$1 = _TopLevelKt$1Class.staticMethodId(
r'getTopLevelField',
r'()I',
);

final _getTopLevelField$1 = jni$_.ProtectedJniExtensions.lookup<
jni$_.NativeFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
)>>('globalEnv_CallStaticIntMethod')
.asFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
)>();

/// from: `static public final int getTopLevelField()`
int getTopLevelField$1() {
return _getTopLevelField$1(_TopLevelKt$1Class.reference.pointer,
_id_getTopLevelField$1 as jni$_.JMethodIDPtr)
.integer;
}

final _id_setTopLevelField$1 = _TopLevelKt$1Class.staticMethodId(
r'setTopLevelField',
r'(I)V',
);

final _setTopLevelField$1 = jni$_.ProtectedJniExtensions.lookup<
jni$_.NativeFunction<
jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Int32,)>)>>(
'globalEnv_CallStaticVoidMethod')
.asFunction<
jni$_.JThrowablePtr Function(
jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();

/// from: `static public final void setTopLevelField(int i)`
void setTopLevelField$1(
int i,
) {
_setTopLevelField$1(_TopLevelKt$1Class.reference.pointer,
_id_setTopLevelField$1 as jni$_.JMethodIDPtr, i)
.check();
}

final _id_topLevel$1 = _TopLevelKt$1Class.staticMethodId(
r'topLevel',
r'()I',
);

final _topLevel$1 = jni$_.ProtectedJniExtensions.lookup<
jni$_.NativeFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
)>>('globalEnv_CallStaticIntMethod')
.asFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
)>();

/// from: `static public final int topLevel()`
int topLevel$1() {
return _topLevel$1(_TopLevelKt$1Class.reference.pointer,
_id_topLevel$1 as jni$_.JMethodIDPtr)
.integer;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* 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.
*/

package com.github.dart_lang.jnigen.subpackage

// The same property and function defined in `../TopLevel.kt` to test renaming.

var topLevelField: Int = 42

fun topLevel(): Int {
return 42
}
4 changes: 4 additions & 0 deletions pkgs/jnigen/test/kotlin_test/runtime_test_registrant.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ void registerTests(String groupName, TestRunnerCallback test) {

test('Top levels', () {
expect(topLevel(), 42);
expect(topLevel$1(), 42);
expect(topLevelSum(10, 20), 30);
expect(getTopLevelField(), 42);
expect(getTopLevelField$1(), 42);
setTopLevelField(30);
setTopLevelField$1(30);
expect(getTopLevelField(), 30);
expect(getTopLevelField$1(), 30);
});

test('Generics', () {
Expand Down
Loading