Skip to content

Commit 9c16b25

Browse files
committed
Add integerValue to IntegerLiteralExprSyntax
1 parent 5bd6384 commit 9c16b25

File tree

3 files changed

+89
-29
lines changed

3 files changed

+89
-29
lines changed

Sources/SwiftRefactor/IntegerLiteralUtilities.swift

-29
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,6 @@ import SwiftSyntax
1717
#endif
1818

1919
extension IntegerLiteralExprSyntax {
20-
public enum Radix {
21-
case binary
22-
case octal
23-
case decimal
24-
case hex
25-
26-
public var size: Int {
27-
switch self {
28-
case .binary: return 2
29-
case .octal: return 8
30-
case .decimal: return 10
31-
case .hex: return 16
32-
}
33-
}
34-
}
35-
36-
public var radix: Radix {
37-
let text = self.literal.text
38-
if text.starts(with: "0b") {
39-
return .binary
40-
} else if text.starts(with: "0o") {
41-
return .octal
42-
} else if text.starts(with: "0x") {
43-
return .hex
44-
} else {
45-
return .decimal
46-
}
47-
}
48-
4920
/// Returns an (arbitrarily) "ideal" number of digits that should constitute
5021
/// a separator-delimited "group" in an integer literal.
5122
var idealGroupSize: Int {

Sources/SwiftSyntax/Convenience.swift

+62
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,68 @@ extension EnumCaseParameterSyntax {
6868
}
6969
}
7070

71+
extension IntegerLiteralExprSyntax {
72+
public enum Radix {
73+
case binary
74+
case octal
75+
case decimal
76+
case hex
77+
78+
public var size: Int {
79+
switch self {
80+
case .binary: return 2
81+
case .octal: return 8
82+
case .decimal: return 10
83+
case .hex: return 16
84+
}
85+
}
86+
87+
fileprivate var offset: Int {
88+
switch self {
89+
case .binary:
90+
return 2
91+
case .octal:
92+
return 2
93+
case .hex:
94+
return 2
95+
case .decimal:
96+
return 0
97+
}
98+
}
99+
}
100+
101+
public var radix: Radix {
102+
let text = self.literal.text
103+
if text.starts(with: "0b") {
104+
return .binary
105+
} else if text.starts(with: "0o") {
106+
return .octal
107+
} else if text.starts(with: "0x") {
108+
return .hex
109+
} else {
110+
return .decimal
111+
}
112+
}
113+
114+
/// A computed property representing the integer value parsed from the associated `literal.text` property, considering the specified radix.
115+
///
116+
/// - Returns: An integer value parsed from the associated `literal.text`, or `nil` if the text cannot be parsed as an integer.
117+
public var representedLiteralValue: Int? {
118+
guard !hasError else { return nil }
119+
120+
let text = literal.text
121+
let radix = self.radix
122+
let digitsStartIndex = text.index(text.startIndex, offsetBy: radix.offset)
123+
let textWithoutPrefix = text.suffix(from: digitsStartIndex)
124+
125+
let textWithoutPrefixOrUnderscores = textWithoutPrefix.filter {
126+
$0 != "_"
127+
}
128+
129+
return Int(textWithoutPrefixOrUnderscores, radix: radix.size)
130+
}
131+
}
132+
71133
extension MemberAccessExprSyntax {
72134
/// Creates a new ``MemberAccessExprSyntax`` where the accessed member is represented by
73135
/// an identifier without specifying argument labels.

Tests/SwiftSyntaxTest/SyntaxTests.swift

+27
Original file line numberDiff line numberDiff line change
@@ -168,4 +168,31 @@ class SyntaxTests: XCTestCase {
168168
XCTAssertEqual(funcKeywordInTree2?.as(TokenSyntax.self)?.tokenKind, .keyword(.func))
169169
XCTAssertNotEqual(funcKeywordInTree1.id, funcKeywordInTree2?.id)
170170
}
171+
172+
func testIntegerLiteralExprSyntax() {
173+
let testCases: [UInt: (String, Int?)] = [
174+
#line: ("2", 2),
175+
#line: ("02", 2),
176+
#line: ("020", 20),
177+
#line: ("-02", -2),
178+
#line: ("2_00_0000", 2_00_0000),
179+
#line: ("-2_00_0000", -2_00_0000),
180+
#line: ("foo", nil),
181+
#line: ("999999999999999999999999999999999999999999999999999999999999999999999999999999", nil),
182+
#line: ("0b1010101", 85),
183+
#line: ("0xFF", 255),
184+
#line: ("0o777", 511),
185+
#line: ("0b001100", 0b001100),
186+
#line: ("4_2", 4_2),
187+
#line: ("0o3434", 0o3434),
188+
#line: ("0xba11aD", 0xba11aD),
189+
#line: ("🐋", nil),
190+
]
191+
192+
for (line, testCase) in testCases {
193+
let (value, expected) = testCase
194+
let expr = IntegerLiteralExprSyntax(literal: .integerLiteral(value))
195+
XCTAssertEqual(expr.representedLiteralValue, expected, line: line)
196+
}
197+
}
171198
}

0 commit comments

Comments
 (0)