Skip to content

Commit 16f0ed7

Browse files
authored
[ffigen] Prevent imported types from being renamed. (#2791)
1 parent 9439bfb commit 16f0ed7

File tree

6 files changed

+50
-5
lines changed

6 files changed

+50
-5
lines changed

pkgs/ffigen/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
NS_OPTIONS enums.
1818
- Fix [a bug](https://github.com/dart-lang/native/issues/2760) in the internal
1919
variables generated by function bindings.
20+
- Fix [a bug](https://github.com/dart-lang/native/issues/2762) where types
21+
imported from package:objective_c could be renamed.
2022

2123
## 20.0.0
2224

pkgs/ffigen/lib/src/code_generator/binding.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ abstract class Binding extends AstNode implements Declaration {
4343
required Symbol symbol,
4444
this.dartDoc,
4545
this.isInternal = false,
46-
}) : _symbol = symbol;
46+
}) : _symbol = symbol {
47+
// Ideally isImported would be part of the Symbol constructor, but then we
48+
// wouldn't be able to use this.isObjCImport.
49+
_symbol.isImported = isObjCImport;
50+
}
4751

4852
/// Converts a Binding to its actual string representation.
4953
///

pkgs/ffigen/lib/src/code_generator/scope.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ class Scope {
7979
_namer = namer;
8080
for (final symbol in _symbols) {
8181
if (symbol._name == null) {
82-
symbol._name = namer.add(symbol.oldName, symbol.kind);
82+
symbol._name = symbol.isImported
83+
? symbol.oldName
84+
: namer.add(symbol.oldName, symbol.kind);
8385
} else {
8486
// Symbol already has a name. This can happen if the symbol is in
8587
// multiple scopes. It's fine as long as the name isn't used by a
@@ -161,6 +163,7 @@ class Namer {
161163
class Symbol extends AstNode {
162164
final String oldName;
163165
final SymbolKind kind;
166+
bool isImported = false;
164167
String? _name;
165168

166169
/// Only valid if [Scope.fillNames] has been called already.

pkgs/ffigen/test/native_objc_test/category_config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ objc-interfaces:
88
- Thing
99
- ChildOfThing
1010
- NSURL
11+
- ChildOfNSString
1112
objc-categories:
1213
include:
1314
- Sub
@@ -16,6 +17,7 @@ objc-categories:
1617
- InstanceTypeCategory
1718
- InterfaceOnBuiltInType
1819
- StaticAndInstanceMethodsWithSameNameCategory
20+
- NSString
1921
headers:
2022
entry-points:
2123
- 'category_test.h'

pkgs/ffigen/test/native_objc_test/category_test.dart

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import 'dart:ffi';
88
import 'dart:io';
99

10-
import 'package:objective_c/objective_c.dart';
10+
import 'package:objective_c/objective_c.dart' as objc;
1111
import 'package:path/path.dart' as path;
1212
import 'package:test/test.dart';
1313

@@ -87,14 +87,14 @@ void main() {
8787
'GoodbyeWorld!',
8888
);
8989

90-
NSString str2 = str.instancetypeMethod();
90+
objc.NSString str2 = str.instancetypeMethod();
9191
expect(str2.toDartString(), 'Hello');
9292
});
9393

9494
test('Transitive category on built-in type', () {
9595
// Regression test for https://github.com/dart-lang/native/issues/1820.
9696
// Include transitive category of explicitly included buit-in type.
97-
expect(NSURL.alloc().extensionMethod(), 555);
97+
expect(objc.NSURL.alloc().extensionMethod(), 555);
9898

9999
// Don't include transitive category of built-in type that hasn't been
100100
// explicitly included.
@@ -111,5 +111,29 @@ void main() {
111111
// This method is from an NSObject extension, which shouldn't be included.
112112
expect(bindings, isNot(contains('autoContentAccessingProxy')));
113113
});
114+
115+
test('Category that has the same name as an imported type that is the '
116+
'supertype of another type in the same file', () {
117+
// Regression test for https://github.com/dart-lang/native/issues/2762.
118+
final bindings = File(
119+
path.join(
120+
packagePathForTests,
121+
'test',
122+
'native_objc_test',
123+
'category_bindings.dart',
124+
),
125+
).readAsStringSync();
126+
127+
// Neither the NSString category, nor the NSString that's a supertype of
128+
// ChildOfNSString, have been renamed to NSString$1.
129+
expect(bindings, contains('extension NSString on Thing {'));
130+
expect(
131+
bindings,
132+
contains('''
133+
extension type ChildOfNSString._(objc.ObjCObject object\$)
134+
implements objc.ObjCObject, objc.NSString {
135+
'''),
136+
);
137+
});
114138
});
115139
}

pkgs/ffigen/test/native_objc_test/category_test.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,13 @@
5959
-(int32_t)sameNameMethod;
6060
+(int32_t)sameNameMethod;
6161
@end
62+
63+
// Category with the same name as a built in type.
64+
@interface Thing (NSString)
65+
-(int32_t)nsStringExtension;
66+
@end
67+
68+
// Extend the object with the same-named category.
69+
// https://github.com/dart-lang/native/issues/2762
70+
@interface ChildOfNSString : NSString {}
71+
@end

0 commit comments

Comments
 (0)