Skip to content

Commit 3229cfb

Browse files
authored
[swift2objc] Support properties that throw (#1939)
1 parent cb3cd34 commit 3229cfb

File tree

6 files changed

+127
-16
lines changed

6 files changed

+127
-16
lines changed

pkgs/swift2objc/lib/src/parser/parsers/declaration_parsers/parse_variable_declaration.dart

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,6 @@ bool _parseVariableIsConstant(Json variableSymbolJson) {
7272
bool _parseVariableThrows(Json json) {
7373
final throws = json['declarationFragments']
7474
.any((frag) => matchFragment(frag, 'keyword', 'throws'));
75-
if (throws) {
76-
// TODO(https://github.com/dart-lang/native/issues/1765): Support throwing
77-
// getters.
78-
throw Exception("Throwing getters aren't supported yet, at ${json.path}");
79-
}
8075
return throws;
8176
}
8277

pkgs/swift2objc/lib/src/transformer/transformers/transform_compound.dart

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import '../../ast/_core/shared/parameter.dart';
99
import '../../ast/declarations/built_in/built_in_declaration.dart';
1010
import '../../ast/declarations/compounds/class_declaration.dart';
1111
import '../../ast/declarations/compounds/members/initializer_declaration.dart';
12+
import '../../ast/declarations/compounds/members/method_declaration.dart';
1213
import '../../ast/declarations/compounds/members/property_declaration.dart';
1314
import '../../parser/_core/utils.dart';
1415
import '../_core/unique_namer.dart';
@@ -51,16 +52,15 @@ ClassDeclaration transformCompound(
5152
transformedCompound.nestedDeclarations
5253
.fillNestingParents(transformedCompound);
5354

54-
transformedCompound.properties = originalCompound.properties
55+
final transformedProperties = originalCompound.properties
5556
.map((property) => transformProperty(
5657
property,
5758
wrappedCompoundInstance,
5859
parentNamer,
5960
transformationMap,
6061
))
6162
.nonNulls
62-
.toList()
63-
..sort((Declaration a, Declaration b) => a.id.compareTo(b.id));
63+
.toList();
6464

6565
transformedCompound.initializers = originalCompound.initializers
6666
.map((initializer) => transformInitializer(
@@ -72,17 +72,25 @@ ClassDeclaration transformCompound(
7272
.toList()
7373
..sort((Declaration a, Declaration b) => a.id.compareTo(b.id));
7474

75-
transformedCompound.methods = originalCompound.methods
75+
final transformedMethods = originalCompound.methods
7676
.map((method) => transformMethod(
7777
method,
7878
wrappedCompoundInstance,
7979
parentNamer,
8080
transformationMap,
8181
))
8282
.nonNulls
83+
.toList();
84+
85+
transformedCompound.properties = transformedProperties
86+
.whereType<PropertyDeclaration>()
8387
.toList()
8488
..sort((Declaration a, Declaration b) => a.id.compareTo(b.id));
8589

90+
transformedCompound.methods = (transformedMethods +
91+
transformedProperties.whereType<MethodDeclaration>().toList())
92+
..sort((Declaration a, Declaration b) => a.id.compareTo(b.id));
93+
8694
return transformedCompound;
8795
}
8896

pkgs/swift2objc/lib/src/transformer/transformers/transform_globals.dart

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import '../../ast/_core/interfaces/declaration.dart';
22
import '../../ast/declarations/built_in/built_in_declaration.dart';
33
import '../../ast/declarations/compounds/class_declaration.dart';
4+
import '../../ast/declarations/compounds/members/method_declaration.dart';
5+
import '../../ast/declarations/compounds/members/property_declaration.dart';
46
import '../../ast/declarations/globals/globals.dart';
57
import '../../parser/_core/utils.dart';
68
import '../_core/unique_namer.dart';
@@ -21,23 +23,30 @@ ClassDeclaration transformGlobals(
2123
isWrapper: true,
2224
);
2325

24-
transformedGlobals.properties = globals.variables
26+
final transformedProperties = globals.variables
2527
.map((variable) => transformGlobalVariable(
2628
variable,
2729
globalNamer,
2830
transformationMap,
2931
))
30-
.toList()
31-
..sort((Declaration a, Declaration b) => a.id.compareTo(b.id));
32+
.toList();
3233

33-
transformedGlobals.methods = globals.functions
34+
final transformedMethods = globals.functions
3435
.map((function) => transformGlobalFunction(
3536
function,
3637
globalNamer,
3738
transformationMap,
3839
))
40+
.toList();
41+
42+
transformedGlobals.properties = transformedProperties
43+
.whereType<PropertyDeclaration>()
3944
.toList()
4045
..sort((Declaration a, Declaration b) => a.id.compareTo(b.id));
4146

47+
transformedGlobals.methods = (transformedMethods +
48+
transformedProperties.whereType<MethodDeclaration>().toList())
49+
..sort((Declaration a, Declaration b) => a.id.compareTo(b.id));
50+
4251
return transformedGlobals;
4352
}

pkgs/swift2objc/lib/src/transformer/transformers/transform_variable.dart

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import '../../ast/_core/interfaces/declaration.dart';
12
import '../../ast/_core/interfaces/variable_declaration.dart';
3+
import '../../ast/declarations/compounds/members/method_declaration.dart';
24
import '../../ast/declarations/compounds/members/property_declaration.dart';
35
import '../../ast/declarations/globals/globals.dart';
46
import '../_core/unique_namer.dart';
@@ -13,7 +15,7 @@ import 'transform_referred_type.dart';
1315
// through the wrapped class instance in the wrapper class. In global variable
1416
// case, it can be referenced directly since it's not a member of any entity.
1517

16-
PropertyDeclaration? transformProperty(
18+
Declaration? transformProperty(
1719
PropertyDeclaration originalProperty,
1820
PropertyDeclaration wrappedClassInstance,
1921
UniqueNamer globalNamer,
@@ -36,7 +38,7 @@ PropertyDeclaration? transformProperty(
3638
);
3739
}
3840

39-
PropertyDeclaration transformGlobalVariable(
41+
Declaration transformGlobalVariable(
4042
GlobalVariableDeclaration globalVariable,
4143
UniqueNamer globalNamer,
4244
TransformationMap transformationMap,
@@ -54,7 +56,7 @@ PropertyDeclaration transformGlobalVariable(
5456

5557
// -------------------------- Core Implementation --------------------------
5658

57-
PropertyDeclaration _transformVariable(
59+
Declaration _transformVariable(
5860
VariableDeclaration originalVariable,
5961
UniqueNamer globalNamer,
6062
TransformationMap transformationMap, {
@@ -71,6 +73,25 @@ PropertyDeclaration _transformVariable(
7173
? originalVariable.hasSetter
7274
: !originalVariable.isConstant;
7375

76+
if (originalVariable.throws) {
77+
return MethodDeclaration(
78+
id: originalVariable.id,
79+
name: wrapperPropertyName,
80+
returnType: transformedType,
81+
params: [],
82+
hasObjCAnnotation: true,
83+
isStatic: originalVariable is PropertyDeclaration
84+
? originalVariable.isStatic
85+
: true,
86+
statements: [
87+
'let result = try $variableReferenceExpression',
88+
'return $transformedType(result)',
89+
],
90+
throws: true,
91+
async: originalVariable.async,
92+
);
93+
}
94+
7495
final transformedProperty = PropertyDeclaration(
7596
id: originalVariable.id,
7697
name: wrapperPropertyName,
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import Foundation
2+
3+
public class MyClass {
4+
public init(y: Int) throws {}
5+
6+
public var classGetter: MyClass {
7+
get throws {
8+
try MyClass(y: 3)
9+
}
10+
}
11+
public var otherClassGetter: OtherClass {
12+
get throws {
13+
OtherClass()
14+
}
15+
}
16+
}
17+
18+
public class OtherClass {}
19+
20+
public var globalClassGetter: MyClass {
21+
get throws {
22+
try MyClass(y: 4)
23+
}
24+
}
25+
public var globalOtherClassGetter: OtherClass {
26+
get throws {
27+
OtherClass()
28+
}
29+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Test preamble text
2+
3+
import Foundation
4+
5+
@objc public class GlobalsWrapper: NSObject {
6+
@objc static public func globalClassGetterWrapper() throws -> MyClassWrapper {
7+
let result = try globalClassGetter
8+
return MyClassWrapper(result)
9+
}
10+
11+
@objc static public func globalOtherClassGetterWrapper() throws -> OtherClassWrapper {
12+
let result = try globalOtherClassGetter
13+
return OtherClassWrapper(result)
14+
}
15+
16+
}
17+
18+
@objc public class OtherClassWrapper: NSObject {
19+
var wrappedInstance: OtherClass
20+
21+
init(_ wrappedInstance: OtherClass) {
22+
self.wrappedInstance = wrappedInstance
23+
}
24+
25+
}
26+
27+
@objc public class MyClassWrapper: NSObject {
28+
var wrappedInstance: MyClass
29+
30+
init(_ wrappedInstance: MyClass) {
31+
self.wrappedInstance = wrappedInstance
32+
}
33+
34+
@objc init(y: Int) throws {
35+
wrappedInstance = try MyClass(y: y)
36+
}
37+
38+
@objc public func otherClassGetter() throws -> OtherClassWrapper {
39+
let result = try wrappedInstance.otherClassGetter
40+
return OtherClassWrapper(result)
41+
}
42+
43+
@objc public func classGetter() throws -> MyClassWrapper {
44+
let result = try wrappedInstance.classGetter
45+
return MyClassWrapper(result)
46+
}
47+
48+
}
49+

0 commit comments

Comments
 (0)