Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class PropertyDeclaration extends AstNode
@override
InputConfig? source;

int? lineNumber;

@override
List<AvailabilityInfo> availability;

Expand All @@ -45,6 +47,8 @@ class PropertyDeclaration extends AstNode

bool hasSetter;

bool hasExplicitGetter;

PropertyStatements? getter;
PropertyStatements? setter;

Expand All @@ -62,11 +66,13 @@ class PropertyDeclaration extends AstNode
required this.source,
required this.availability,
required this.type,
this.lineNumber,
this.hasSetter = false,
this.isConstant = false,
this.hasObjCAnnotation = false,
this.getter,
this.setter,
this.hasExplicitGetter = false,
this.isStatic = false,
this.throws = false,
this.async = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,37 @@ PropertyDeclaration parsePropertyDeclaration(
bool isStatic = false,
}) {
final info = parsePropertyInfo(symbol.json['declarationFragments']);

// Extract line number from location
int? lineNumber;
final locationJson = symbol.json['location'];
if (locationJson.exists) {
final positionJson = locationJson['position'];
if (positionJson.exists) {
final lineJson = positionJson['line'];
if (lineJson.exists) {
lineNumber = lineJson.get<int>();
}
}
}

return PropertyDeclaration(
id: parseSymbolId(symbol.json),
name: parseSymbolName(symbol.json),
source: symbol.source,
availability: parseAvailability(symbol.json),
type: _parseVariableType(context, symbol.json, symbolgraph),
hasObjCAnnotation: parseSymbolHasObjcAnnotation(symbol.json),
lineNumber: lineNumber,
isConstant: info.constant,
isStatic: isStatic,
throws: info.throws,
async: info.async,
unowned: info.unowned,
weak: info.weak,
lazy: info.lazy,
hasSetter: info.constant ? false : info.setter,
hasSetter: info.constant ? false : (info.getter ? info.setter : true),
hasExplicitGetter: info.getter,
);
}

Expand Down Expand Up @@ -139,7 +155,7 @@ ParsedPropertyInfo parsePropertyInfo(Json json) {
);
} else {
// has implicit getter and implicit setter
return (true, true);
return (false, false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
import '../../ast/_core/interfaces/compound_declaration.dart';
import '../../ast/_core/interfaces/declaration.dart';
import '../../ast/_core/interfaces/nestable_declaration.dart';
import '../../ast/_core/shared/parameter.dart';
import '../../ast/declarations/built_in/built_in_declaration.dart';
import '../../ast/declarations/compounds/class_declaration.dart';
import '../../ast/declarations/compounds/members/initializer_declaration.dart';
import '../../ast/declarations/compounds/members/method_declaration.dart';
import '../../ast/declarations/compounds/members/property_declaration.dart';
import '../../ast/declarations/compounds/struct_declaration.dart';
import '../../parser/_core/utils.dart';
import '../_core/unique_namer.dart';
import '../_core/utils.dart';
Expand Down Expand Up @@ -79,7 +81,7 @@ ClassDeclaration transformCompound(
.nonNulls
.toList();

final transformedInitializers = originalCompound.initializers
final transformedInitializers = _compoundInitializers(originalCompound)
.map(
(initializer) => transformInitializer(
initializer,
Expand Down Expand Up @@ -122,3 +124,44 @@ ClassDeclaration transformCompound(

return transformedCompound;
}

List<InitializerDeclaration> _compoundInitializers(
CompoundDeclaration originalCompound,
) {
final initializers = originalCompound.initializers;
if (originalCompound is! StructDeclaration || initializers.isNotEmpty) {
return initializers;
}
final storedProperties =
originalCompound.properties
.where((prop) => !prop.isStatic && !prop.hasExplicitGetter)
.toList()
..sort((a, b) {
final aLine = a.lineNumber ?? 0;
final bLine = b.lineNumber ?? 0;
return aLine.compareTo(bLine);
});

if (storedProperties.isEmpty) {
return initializers;
}

final implicitInit = InitializerDeclaration(
id: originalCompound.id.addIdSuffix('implicit_init'),
source: originalCompound.source,
availability: originalCompound.availability,
params: storedProperties
.map(
(prop) =>
Parameter(name: prop.name, internalName: null, type: prop.type),
)
.toList(),
hasObjCAnnotation: true,
isOverriding: false,
throws: false,
async: false,
isFailable: false,
);

return [implicitInit];
}
9 changes: 6 additions & 3 deletions pkgs/swift2objc/test/integration/available_output.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import Foundation
get {
globalVar
}
set {
globalVar = newValue
}
}

@available(macOS, introduced: 234.5.6)
Expand Down Expand Up @@ -110,6 +107,12 @@ import Foundation
self.wrappedInstance = wrappedInstance
}

@available(macOS, introduced: 123.0.0)
@available(iOS, introduced: 100)
@objc public init(prop1: Int, prop2: Int) {
wrappedInstance = NewStruct(prop1: prop1, prop2: prop2)
}

@available(macOS, introduced: 123.0.0)
@available(iOS, introduced: 100)
@objc public func method1() -> Int {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ import Foundation
get {
MyOtherClassWrapper(globalCustomVariable)
}
set {
globalCustomVariable = newValue.wrappedInstance
}
}

@objc static public var globalGetterVariableWrapper: Double {
Expand Down Expand Up @@ -43,9 +40,6 @@ import Foundation
get {
globalRepresentableVariable
}
set {
globalRepresentableVariable = newValue
}
}

@objc static public func globalCustomFunctionWrapper(label1 param1: Int, param2: MyOtherClassWrapper) -> MyOtherClassWrapper {
Expand Down
31 changes: 31 additions & 0 deletions pkgs/swift2objc/test/integration/implicit_initializers_input.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
public struct MyPerson {
public var name: String
public var age: Int
}

public struct MyConfig {
public var title: String
public var count: Int
public var enabled: Bool
}

public struct MyCustomStruct {
public var data: Int

public init(value: Int) {
self.data = value * 2
}
}

public struct MyStaticStruct {
public static var defaultName = "Default"
public var name: String
}

public struct MyComputedStruct {
public var firstName: String
public var lastName: String
public var fullName: String {
return "\(firstName) \(lastName)"
}
}
165 changes: 165 additions & 0 deletions pkgs/swift2objc/test/integration/implicit_initializers_output.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Test preamble text

import Foundation

@objc public class MyCustomStructWrapper: NSObject {
var wrappedInstance: MyCustomStruct

@objc public var data: Int {
get {
wrappedInstance.data
}
set {
wrappedInstance.data = newValue
}
}

init(_ wrappedInstance: MyCustomStruct) {
self.wrappedInstance = wrappedInstance
}

@objc public init(value: Int) {
wrappedInstance = MyCustomStruct(value: value)
}

}

@objc public class MyStaticStructWrapper: NSObject {
var wrappedInstance: MyStaticStruct

@objc static public var defaultName: String {
get {
MyStaticStruct.defaultName
}
set {
MyStaticStruct.defaultName = newValue
}
}

@objc public var name: String {
get {
wrappedInstance.name
}
set {
wrappedInstance.name = newValue
}
}

init(_ wrappedInstance: MyStaticStruct) {
self.wrappedInstance = wrappedInstance
}

@objc public init(name: String) {
wrappedInstance = MyStaticStruct(name: name)
}

}

@objc public class MyComputedStructWrapper: NSObject {
var wrappedInstance: MyComputedStruct

@objc public var fullName: String {
get {
wrappedInstance.fullName
}
}

@objc public var lastName: String {
get {
wrappedInstance.lastName
}
set {
wrappedInstance.lastName = newValue
}
}

@objc public var firstName: String {
get {
wrappedInstance.firstName
}
set {
wrappedInstance.firstName = newValue
}
}

init(_ wrappedInstance: MyComputedStruct) {
self.wrappedInstance = wrappedInstance
}

@objc public init(firstName: String, lastName: String) {
wrappedInstance = MyComputedStruct(firstName: firstName, lastName: lastName)
}

}

@objc public class MyConfigWrapper: NSObject {
var wrappedInstance: MyConfig

@objc public var count: Int {
get {
wrappedInstance.count
}
set {
wrappedInstance.count = newValue
}
}

@objc public var title: String {
get {
wrappedInstance.title
}
set {
wrappedInstance.title = newValue
}
}

@objc public var enabled: Bool {
get {
wrappedInstance.enabled
}
set {
wrappedInstance.enabled = newValue
}
}

init(_ wrappedInstance: MyConfig) {
self.wrappedInstance = wrappedInstance
}

@objc public init(title: String, count: Int, enabled: Bool) {
wrappedInstance = MyConfig(title: title, count: count, enabled: enabled)
}

}

@objc public class MyPersonWrapper: NSObject {
var wrappedInstance: MyPerson

@objc public var age: Int {
get {
wrappedInstance.age
}
set {
wrappedInstance.age = newValue
}
}

@objc public var name: String {
get {
wrappedInstance.name
}
set {
wrappedInstance.name = newValue
}
}

init(_ wrappedInstance: MyPerson) {
self.wrappedInstance = wrappedInstance
}

@objc public init(name: String, age: Int) {
wrappedInstance = MyPerson(name: name, age: age)
}

}

3 changes: 0 additions & 3 deletions pkgs/swift2objc/test/integration/optional_output.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ import Foundation
get {
globalOptional == nil ? nil : MyStructWrapper(globalOptional!)
}
set {
globalOptional = newValue?.wrappedInstance
}
}

@objc static public func funcOptionalArgsWrapper(label param: MyClassWrapper?) -> MyClassWrapper {
Expand Down
Loading
Loading