Skip to content

Commit 15f248e

Browse files
committed
Improve nullability / initializers
Additionally: - add initializers for types - misc fix for GIL checking
1 parent 7fbae99 commit 15f248e

File tree

9 files changed

+104
-85
lines changed

9 files changed

+104
-85
lines changed

Sources/Vim/Vim.swift

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,27 @@ public struct Vim {
66
}
77

88
/// Run a vim command
9-
@discardableResult public static func command(_ cmd: String) -> VimValue {
10-
var value: VimValue!
9+
@discardableResult public static func command(_ cmd: String) -> VimValue? {
10+
var value: VimValue?
1111
cmd.withCString { cStr in
1212
//FIXME: handle error propagation
13-
let result = swiftvim_command(
14-
UnsafeMutablePointer(mutating: cStr))
15-
value = VimValue(value: result)
13+
if let result = swiftvim_command(
14+
UnsafeMutablePointer(mutating: cStr)) {
15+
value = VimValue(result)
16+
}
1617
}
1718
return value
1819
}
1920

2021
/// Evaluate an expression
21-
@discardableResult public static func eval(_ cmd: String) -> VimValue {
22-
var value: VimValue!
22+
@discardableResult public static func eval(_ cmd: String) -> VimValue? {
23+
var value: VimValue?
2324
cmd.withCString { cStr in
2425
//FIXME: handle error propagation
25-
let result = swiftvim_eval(
26-
UnsafeMutablePointer(mutating: cStr))
27-
value = VimValue(value: result)
26+
if let result = swiftvim_eval(
27+
UnsafeMutablePointer(mutating: cStr)) {
28+
value = VimValue(result)
29+
}
2830
}
2931
return value
3032
}

Sources/Vim/VimBuffer.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import VimInterface
22

33
public class VimBuffer {
4-
private let value: UnsafeVimValue
4+
private let value: VimValue
55

6-
init(value: UnsafeVimValue) {
6+
init(_ value: VimValue) {
77
self.value = value
88
}
99

1010
public lazy var number: Int = {
11-
return self.value.attr("number")
11+
return self.value.reference.attr("number")
1212
}()
1313

1414
public lazy var name: String = {
15-
return self.value.attr("name")
15+
return self.value.reference.attr("name")
1616
}()
1717

1818
public func asList() -> VimList {
19-
return VimList(value: self.value)
19+
return VimList(self.value)
2020
}
2121
}

Sources/Vim/VimCurrent.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ public class Current {
44
private let value: UnsafeVimValue
55

66
public lazy var buffer: VimBuffer = {
7-
return VimBuffer(value: self.value.attrp("buffer")!)
7+
return VimBuffer(VimValue(self.value.attrp("buffer")!))
88
}()
99

1010
public lazy var window: VimWindow = {
11-
return VimWindow(value: self.value.attrp("window")!)
11+
return VimWindow(VimValue(self.value.attrp("window")!))
1212
}()
1313

1414
init() {

Sources/Vim/VimValue.swift

Lines changed: 64 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,109 +1,130 @@
11
import VimInterface
22

3+
4+
extension Int {
5+
init?(_ value: VimValue) {
6+
// Generally, eval results are returned as strings
7+
// Perhaps there is a better way to express this.
8+
if let strValue = value.asString(),
9+
let intValue = Int(strValue) {
10+
self.init(intValue)
11+
} else {
12+
self.init(swiftvim_asint(value.reference))
13+
}
14+
}
15+
}
16+
17+
extension String {
18+
init?(_ value: VimValue) {
19+
guard let cStr = swiftvim_asstring(value.reference) else {
20+
return nil
21+
}
22+
self.init(cString: cStr)
23+
}
24+
}
25+
326
/// Vim Value represents a value in Vim
427
///
528
/// This value is generally created from vimscript function calls. It provides
629
/// a "readonly" view of Vim's state.
730
public final class VimValue {
8-
fileprivate let value: UnsafeVimValue?
31+
let reference: UnsafeVimValue
932
private let doDeInit: Bool
1033

11-
init(value: UnsafeVimValue?, doDeInit: Bool = false) {
12-
self.value = value
34+
init(_ value: UnsafeVimValue, doDeInit: Bool = false) {
35+
self.reference = value
1336
self.doDeInit = doDeInit
1437
}
1538

39+
/// Borrowed reference
40+
init(borrowedReference: UnsafeVimValue) {
41+
self.reference = borrowedReference
42+
self.doDeInit = false
43+
}
44+
45+
init(reference: UnsafeVimValue) {
46+
// FIXME: Audit spmvim_lib.c for cases of this
47+
self.reference = reference
48+
self.doDeInit = true
49+
}
50+
1651
deinit {
1752
/// Correctly decrement when this value is done.
1853
if doDeInit {
19-
swiftvim_decref(value)
54+
swiftvim_decref(reference)
2055
}
2156
}
57+
}
2258

23-
// Mark - Casting
24-
59+
/// Casting extensions
60+
extension VimValue {
2561
public func asString() -> String? {
26-
guard let value = self.value else { return nil }
27-
guard let cStr = swiftvim_asstring(value) else {
28-
return nil
29-
}
30-
return String(cString: cStr)
62+
return String(self)
3163
}
3264

3365
public func asInt() -> Int? {
34-
// Generally, eval results are returned as strings
35-
// Perhaps there is a better way to express this.
36-
if let strValue = asString(),
37-
let value = Int(strValue) {
38-
return value
39-
}
40-
guard let value = self.value else { return nil }
41-
return Int(swiftvim_asint(value))
66+
return Int(self)
4267
}
4368

4469
public func asList() -> VimList? {
45-
guard let value = self.value else { return nil }
46-
return VimList(value: value)
70+
return VimList(self)
4771
}
4872

4973
public func asDictionary() -> VimDictionary? {
50-
guard let value = self.value else { return nil }
51-
return VimDictionary(value: value)
74+
return VimDictionary(self)
5275
}
5376
}
5477

5578
// A Dictionary
5679
public final class VimDictionary {
57-
private let value: UnsafeVimValue
80+
private let value: VimValue
5881

59-
fileprivate init(value: UnsafeVimValue) {
82+
fileprivate init(_ value: VimValue) {
6083
self.value = value
6184
}
6285

6386
public var count: Int {
64-
return Int(swiftvim_dict_size(value))
87+
return Int(swiftvim_dict_size(value.reference))
6588
}
6689

6790
public var keys: VimList {
68-
guard let list = VimValue(value: swiftvim_dict_keys(value),
69-
doDeInit: false).asList() else {
91+
guard let list = VimValue(reference: swiftvim_dict_keys(value.reference)).asList() else {
7092
fatalError("Can't get keys")
7193
}
7294
return list
7395
}
7496

7597
public var values: VimList {
76-
guard let list = VimValue(value: swiftvim_dict_values(value),
77-
doDeInit: false).asList() else {
98+
guard let list = VimValue(reference: swiftvim_dict_values(value.reference)).asList() else {
7899
fatalError("Can't get values")
79100
}
80101
return list
81102
}
82103

83104
public subscript(index: VimValue) -> VimValue? {
84105
get {
85-
guard let v = swiftvim_dict_get(value, index.value) else {
106+
guard let v = swiftvim_dict_get(value.reference, index.reference) else {
86107
return nil
87108
}
88-
return VimValue(value: v)
109+
return VimValue(v)
89110
}
90111
set {
91-
swiftvim_dict_set(value, index.value!, newValue?.value)
112+
swiftvim_dict_set(value.reference, index.reference, newValue?.reference)
92113
}
93114
}
94115

95116
public subscript(index: String) -> VimValue? {
96117
get {
97118
return index.withCString { cStrIdx in
98-
guard let v = swiftvim_dict_getstr(value, cStrIdx) else {
119+
guard let v = swiftvim_dict_getstr(value.reference, cStrIdx) else {
99120
return nil
100121
}
101-
return VimValue(value: v)
122+
return VimValue(v)
102123
}
103124
}
104125
set {
105126
index.withCString { cStrIdx in
106-
swiftvim_dict_setstr(value, cStrIdx, newValue?.value)
127+
swiftvim_dict_setstr(value.reference, cStrIdx, newValue?.reference)
107128
}
108129
}
109130
}
@@ -112,14 +133,10 @@ public final class VimDictionary {
112133

113134
/// A List of VimValues
114135
public final class VimList: Collection {
115-
private let value: UnsafeVimValue
136+
private let value: VimValue
116137

117138
/// Cast a VimValue to a VimList
118-
public init(_ vimValue: VimValue) {
119-
self.value = vimValue.value!
120-
}
121-
122-
init(value: UnsafeVimValue) {
139+
public init(_ value: VimValue) {
123140
self.value = value
124141
}
125142

@@ -128,23 +145,23 @@ public final class VimList: Collection {
128145
}
129146

130147
public var endIndex: Int {
131-
return Int(swiftvim_list_size(value))
148+
return Int(swiftvim_list_size(value.reference))
132149
}
133150

134151
public var isEmpty: Bool {
135-
return swiftvim_list_size(value) == 0
152+
return swiftvim_list_size(value.reference) == 0
136153
}
137154

138155
public var count: Int {
139-
return Int(swiftvim_list_size(value))
156+
return Int(swiftvim_list_size(value.reference))
140157
}
141158

142159
public subscript(index: Int) -> VimValue {
143160
get {
144-
return VimValue(value: swiftvim_list_get(value, Int32(index)))
161+
return VimValue(swiftvim_list_get(value.reference, Int32(index)))
145162
}
146163
set {
147-
swiftvim_list_set(value, Int32(index), newValue.value)
164+
swiftvim_list_set(value.reference, Int32(index), newValue.reference)
148165
}
149166
}
150167

Sources/Vim/VimWindow.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import VimInterface
22

33
public class VimWindow {
4-
private let value: UnsafeVimValue
4+
private let value: VimValue
55

6-
init(value: UnsafeVimValue) {
6+
init(_ value: VimValue) {
77
self.value = value
88
}
99

1010
public var cursor: (Int, Int) {
11-
guard let cursor = self.value.attrp("cursor") else {
11+
guard let cursor = self.value.reference.attrp("cursor") else {
1212
return (0, 0)
1313
}
1414
let first = swiftvim_tuple_get(cursor, 0)
@@ -17,23 +17,23 @@ public class VimWindow {
1717
}
1818

1919
public var height: Int {
20-
return value.attr("height")
20+
return value.reference.attr("height")
2121
}
2222

2323
public var col: Int {
24-
return value.attr("col")
24+
return value.reference.attr("col")
2525
}
2626

2727
public var row: Int {
28-
return value.attr("row")
28+
return value.reference.attr("row")
2929
}
3030

3131
public var valid: Bool {
32-
return value.attr("valid") != 0
32+
return value.reference.attr("valid") != 0
3333
}
3434

3535
public var buffer: VimBuffer {
36-
return VimBuffer(value: value.attrp("buffer")!)
36+
return VimBuffer(VimValue(reference: value.reference.attrp("buffer")!))
3737
}
3838
}
3939

Sources/VimInterface/include/VimInterface/swiftvim.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void *_Nullable swiftvim_call(const char *_Nonnull module, const char *_Nonnull
4040
void *_Nullable swiftvim_get_module(const char *_Nonnull module);
4141
void *_Nullable swiftvim_get_attr(void *_Nonnull target, const char *_Nonnull attr);
4242

43-
void *_Nullable swiftvim_call_impl(void *func, void *_Nullable arg1, void *_Nullable arg2);
43+
void *_Nullable swiftvim_call_impl(void *_Nonnull func, void *_Nullable arg1, void *_Nullable arg2);
4444

4545
// Bootstrapping
4646
// Note: These methods are only for testing purposes

Sources/VimInterface/swiftvim_lib.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ VIM_INTEN void *swiftvim_call(const char *module, const char *method, const char
6363
PyObject *pFunc = PyObject_GetAttrString(pModule, method);
6464
void *v = swiftvim_call_impl(pFunc, arg, NULL);
6565
Py_DECREF(pModule);
66-
PyGILState_Release(gstate);
6766
Py_XDECREF(pFunc);
67+
PyGILState_Release(gstate);
6868
return v;
6969
}
7070

Sources/VimKit/VimExtensions.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,20 @@ extension Vim {
3232
command("let \(variable) = \(value.toVimScript())")
3333
}
3434

35-
public static func get(variable: String) -> VimValue {
35+
public static func get(variable: String) -> VimValue? {
3636
return eval(variable)
3737
}
3838

39-
public static func get(_ variable: String) -> VimValue {
39+
public static func get(_ variable: String) -> VimValue? {
4040
return eval(variable)
4141
}
4242

4343
public static func get(_ variable: String) -> Bool {
44-
return Bool((eval(variable).asInt() ?? 0) != 0)
44+
return Bool((eval(variable)?.asInt() ?? 0) != 0)
4545
}
4646

4747
public static func get(_ variable: String) -> Int {
48-
return eval(variable).asInt() ?? 0
48+
return eval(variable)?.asInt() ?? 0
4949
}
5050

5151
/// Returns the 0-based current line and 0-based current column

0 commit comments

Comments
 (0)