Skip to content

Commit 1190f9e

Browse files
authored
Fix code generation (#7)
This PR (1) strips comments in macro code generation output, which had led to invalid syntax. For instance ``` struct Header { var value: Int // some comment } ``` generates `__assertParsable(Int // some comment.self)` (2) wraps types in `()` before applying `.self` For instance, `A & B` will previously generate `A & B.self` instead of `(A & B).self`
1 parent c5e4382 commit 1190f9e

File tree

7 files changed

+158
-20
lines changed

7 files changed

+158
-20
lines changed

Sources/BinaryParseKitMacros/Macros/ParseEnum/EnumCaseParseInfo.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ struct EnumCaseParameterParseInfo {
3232
let parseInfo: ParseMacroInfo
3333
let firstName: TokenSyntax?
3434
let type: TypeSyntax
35+
36+
init(parseInfo: ParseMacroInfo, firstName: TokenSyntax?, type: TypeSyntax) {
37+
self.parseInfo = parseInfo
38+
self.firstName = firstName?.trimmed
39+
self.type = type.trimmed
40+
}
3541
}
3642

3743
enum EnumParseAction {
@@ -111,6 +117,12 @@ struct EnumCaseParseInfo {
111117
let matchAction: EnumCaseMatchAction
112118
let parseActions: [EnumParseAction]
113119
let caseElementName: TokenSyntax
120+
121+
init(matchAction: EnumCaseMatchAction, parseActions: [EnumParseAction], caseElementName: TokenSyntax) {
122+
self.matchAction = matchAction
123+
self.parseActions = parseActions
124+
self.caseElementName = caseElementName.trimmed
125+
}
114126
}
115127

116128
struct EnumParseInfo {

Sources/BinaryParseKitMacros/Macros/ParseStruct/ParseStructField.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ class ParseStructField<C: MacroExpansionContext>: SyntaxVisitor {
1515
struct VariableInfo {
1616
let type: TypeSyntax
1717
let parseActions: [StructParseAction]
18+
19+
init(type: TypeSyntax, parseActions: [StructParseAction]) {
20+
self.type = type.trimmed
21+
self.parseActions = parseActions
22+
}
1823
}
1924

2025
typealias ParseVariableMapping = OrderedDictionary<TokenSyntax, VariableInfo>
@@ -102,7 +107,7 @@ class ParseStructField<C: MacroExpansionContext>: SyntaxVisitor {
102107
throw .invalidTypeAnnotation
103108
}
104109

105-
variables[variableName] = .init(type: typeName, parseActions: structFieldVisitor.parseActions)
110+
variables[variableName.trimmed] = .init(type: typeName, parseActions: structFieldVisitor.parseActions)
106111
}
107112

108113
func validate(for node: some SwiftSyntax.SyntaxProtocol) throws(ParseStructMacroError) {

Sources/BinaryParseKitMacros/Macros/Supports/ParseMacroInfo.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ private class ParseMacroArgVisitor<C: MacroExpansionContext>: SyntaxVisitor {
7676

7777
let selfAccessExpr = ExprSyntax("self\(keyPath.components)")
7878

79-
byteCount = .ofVariable(selfAccessExpr)
79+
byteCount = .ofVariable(selfAccessExpr.trimmed)
8080
} else {
8181
byteCount = .unspecified
8282
}
@@ -119,7 +119,7 @@ struct ParseMacroInfo {
119119

120120
init(byteCount: Count, endianness: ExprSyntax? = nil, source: Syntax) {
121121
self.byteCount = byteCount
122-
self.endianness = endianness
122+
self.endianness = endianness?.trimmed
123123
self.source = source
124124
}
125125

Sources/BinaryParseKitMacros/Macros/Supports/Utilities.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func generateParseBlock(
3030
case let (endianness?, size?):
3131
#"""
3232
// Parse `\#(variableName)` of type \#(variableType) with endianness and byte count
33-
\#(raw: Constants.UtilityFunctions.assertEndianSizedParsable)(\#(variableType).self)
33+
\#(raw: Constants.UtilityFunctions.assertEndianSizedParsable)((\#(variableType)).self)
3434
"""#
3535

3636
let assigned: ExprSyntax = #"try \#(variableType)(parsing: &span, endianness: \#(endianness), byteCount: \#(size))"#
@@ -43,7 +43,7 @@ func generateParseBlock(
4343
case (let endianness?, nil):
4444
#"""
4545
// Parse `\#(variableName)` of type \#(variableType) with endianness
46-
\#(raw: Constants.UtilityFunctions.assertEndianParsable)(\#(variableType).self)
46+
\#(raw: Constants.UtilityFunctions.assertEndianParsable)((\#(variableType)).self)
4747
"""#
4848

4949
let assigned: ExprSyntax = #"try \#(variableType)(parsing: &span, endianness: \#(endianness))"#
@@ -56,7 +56,7 @@ func generateParseBlock(
5656
case (nil, let size?):
5757
#"""
5858
// Parse `\#(variableName)` of type \#(variableType) with byte count
59-
\#(raw: Constants.UtilityFunctions.assertSizedParsable)(\#(variableType).self)
59+
\#(raw: Constants.UtilityFunctions.assertSizedParsable)((\#(variableType)).self)
6060
"""#
6161

6262
let assigned: ExprSyntax = #"try \#(variableType)(parsing: &span, byteCount: \#(size))"#
@@ -69,7 +69,7 @@ func generateParseBlock(
6969
case (nil, nil):
7070
#"""
7171
// Parse `\#(variableName)` of type \#(variableType)
72-
\#(raw: Constants.UtilityFunctions.assertParsable)(\#(variableType).self)
72+
\#(raw: Constants.UtilityFunctions.assertParsable)((\#(variableType)).self)
7373
"""#
7474

7575
let assigned: ExprSyntax = #"try \#(variableType)(parsing: &span)"#

Tests/BinaryParseKitMacroTests/BinaryParseKitEnumTests.swift

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,29 +152,29 @@ extension BinaryParseKitMacroTests {
152152
init(parsing span: inout BinaryParsing.ParserSpan) throws(BinaryParsing.ThrownParsingError) {
153153
if BinaryParseKit.__match([0x08], in: &span) {
154154
// Parse `__macro_local_12TestEnum_a_0fMu_` of type SomeType with byte count
155-
BinaryParseKit.__assertSizedParsable(SomeType.self)
155+
BinaryParseKit.__assertSizedParsable((SomeType).self)
156156
let __macro_local_12TestEnum_a_0fMu_ = try SomeType(parsing: &span, byteCount: 1)
157157
// construct `a` with above associated values
158158
self = .a(__macro_local_12TestEnum_a_0fMu_)
159159
return
160160
}
161161
if BinaryParseKit.__match([0x01, 0x02], in: &span) {
162162
// Parse `__macro_local_12TestEnum_b_0fMu_` of type Int
163-
BinaryParseKit.__assertParsable(Int.self)
163+
BinaryParseKit.__assertParsable((Int).self)
164164
let __macro_local_12TestEnum_b_0fMu_ = try Int(parsing: &span)
165165
// Parse `value` of type SomeType with endianness
166-
BinaryParseKit.__assertEndianParsable(SomeType.self)
166+
BinaryParseKit.__assertEndianParsable((SomeType).self)
167167
let value = try SomeType(parsing: &span, endianness: .big)
168168
// construct `b` with above associated values
169169
self = .b(__macro_local_12TestEnum_b_0fMu_, value: value)
170170
return
171171
}
172172
if BinaryParseKit.__match([0x09], in: &span) {
173173
// Parse `code` of type UInt8 with endianness
174-
BinaryParseKit.__assertEndianParsable(UInt8.self)
174+
BinaryParseKit.__assertEndianParsable((UInt8).self)
175175
let code = try UInt8(parsing: &span, endianness: .little)
176176
// Parse `value` of type SomeType with endianness
177-
BinaryParseKit.__assertEndianParsable(SomeType.self)
177+
BinaryParseKit.__assertEndianParsable((SomeType).self)
178178
let value = try SomeType(parsing: &span, endianness: .little)
179179
// construct `c` with above associated values
180180
self = .c(code: code, value: value)
@@ -592,6 +592,84 @@ extension BinaryParseKitMacroTests {
592592
],
593593
)
594594
}
595+
596+
@Test
597+
func `no comments in code generation`() {
598+
assertMacroExpansion("""
599+
@ParseEnum
600+
enum TestEnum {
601+
@match
602+
@parse
603+
case a(
604+
value: Int // some value
605+
)
606+
607+
@match
608+
@parse
609+
case b(
610+
value: // some value
611+
Int // some value
612+
)
613+
614+
@match
615+
@parse
616+
@parse
617+
case c(
618+
Int, // some value
619+
value: // some value
620+
Int // some value
621+
)
622+
}
623+
""", expandedSource: #"""
624+
enum TestEnum {
625+
case a(
626+
value: Int // some value
627+
)
628+
case b(
629+
value: // some value
630+
Int // some value
631+
)
632+
case c(
633+
Int, // some value
634+
value: // some value
635+
Int // some value
636+
)
637+
}
638+
639+
extension TestEnum: BinaryParseKit.Parsable {
640+
init(parsing span: inout BinaryParsing.ParserSpan) throws(BinaryParsing.ThrownParsingError) {
641+
if BinaryParseKit.__match((TestEnum.a as any MatchableRawRepresentable) .bytesToMatch(), in: &span) {
642+
// Parse `value` of type Int
643+
BinaryParseKit.__assertParsable((Int).self)
644+
let value = try Int(parsing: &span)
645+
// construct `a` with above associated values
646+
self = .a(value: value)
647+
return
648+
}
649+
if BinaryParseKit.__match((TestEnum.b as any MatchableRawRepresentable) .bytesToMatch(), in: &span) {
650+
// Parse `value` of type Int
651+
BinaryParseKit.__assertParsable((Int).self)
652+
let value = try Int(parsing: &span)
653+
// construct `b` with above associated values
654+
self = .b(value: value)
655+
return
656+
}
657+
if BinaryParseKit.__match((TestEnum.c as any MatchableRawRepresentable) .bytesToMatch(), in: &span) {
658+
// Parse `__macro_local_12TestEnum_c_0fMu_` of type Int
659+
BinaryParseKit.__assertParsable((Int).self)
660+
let __macro_local_12TestEnum_c_0fMu_ = try Int(parsing: &span)
661+
// Parse `value` of type Int
662+
BinaryParseKit.__assertParsable((Int).self)
663+
let value = try Int(parsing: &span)
664+
// construct `c` with above associated values
665+
self = .c(__macro_local_12TestEnum_c_0fMu_, value: value)
666+
return
667+
}
668+
throw BinaryParseKit.BinaryParserKitError.failedToParse("Failed to find a match for TestEnum, at \(span.startPosition)")
669+
}
670+
}
671+
"""#)
672+
}
595673
}
596674
}
597675

Tests/BinaryParseKitMacroTests/BinaryParseKitStructTests.swift

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,33 +73,33 @@ extension BinaryParseKitMacroTests {
7373
extension Header: BinaryParseKit.Parsable {
7474
public init(parsing span: inout BinaryParsing.ParserSpan) throws(BinaryParsing.ThrownParsingError) {
7575
// Parse `a` of type Int with endianness and byte count
76-
BinaryParseKit.__assertEndianSizedParsable(Int.self)
76+
BinaryParseKit.__assertEndianSizedParsable((Int).self)
7777
self.a = try Int(parsing: &span, endianness: .big, byteCount: 1)
7878
// Parse `b` of type Int32 with endianness
79-
BinaryParseKit.__assertEndianParsable(Int32.self)
79+
BinaryParseKit.__assertEndianParsable((Int32).self)
8080
self.b = try Int32(parsing: &span, endianness: .little)
8181
// Skip 2 because of "not needed", before parsing `d`
8282
try span.seek(toRelativeOffset: 2)
8383
// Skip 4 because of "also not needed", before parsing `d`
8484
try span.seek(toRelativeOffset: 4)
8585
// Parse `d` of type Float16 with endianness
86-
BinaryParseKit.__assertEndianParsable(Float16.self)
86+
BinaryParseKit.__assertEndianParsable((Float16).self)
8787
self.d = try Float16(parsing: &span, endianness: .big)
8888
// Parse `c` of type CustomValue
89-
BinaryParseKit.__assertParsable(CustomValue.self)
89+
BinaryParseKit.__assertParsable((CustomValue).self)
9090
self.c = try CustomValue(parsing: &span)
9191
// Skip 6 because of "again, not needed", before parsing `e`
9292
try span.seek(toRelativeOffset: 6)
9393
// Parse `e` of type CustomValue
94-
BinaryParseKit.__assertParsable(CustomValue.self)
94+
BinaryParseKit.__assertParsable((CustomValue).self)
9595
self.e = try CustomValue(parsing: &span)
9696
// Parse `g` of type CustomValue with byte count
97-
BinaryParseKit.__assertSizedParsable(CustomValue.self)
97+
BinaryParseKit.__assertSizedParsable((CustomValue).self)
9898
self.g = try CustomValue(parsing: &span, byteCount: Int(self.b))
9999
// Skip 7 because of "last one skip", before parsing `f`
100100
try span.seek(toRelativeOffset: 7)
101101
// Parse `f` of type CustomValue with endianness and byte count
102-
BinaryParseKit.__assertEndianSizedParsable(CustomValue.self)
102+
BinaryParseKit.__assertEndianSizedParsable((CustomValue).self)
103103
self.f = try CustomValue(parsing: &span, endianness: .little, byteCount: span.endPosition - span.startPosition)
104104
}
105105
}
@@ -611,6 +611,49 @@ extension BinaryParseKitMacroTests {
611611
],
612612
)
613613
}
614+
615+
@Test
616+
func `no comments and spaces in code generation`() {
617+
assertMacroExpansion("""
618+
@ParseStruct
619+
struct Header {
620+
@parse
621+
var a: Int // some comments
622+
623+
@parse
624+
var b: // some comments
625+
Int // some comments
626+
627+
@parse
628+
var // some comments
629+
c: // some comments
630+
Int // some comments
631+
}
632+
""", expandedSource: """
633+
struct Header {
634+
var a: Int // some comments
635+
var b: // some comments
636+
Int // some comments
637+
var // some comments
638+
c: // some comments
639+
Int // some comments
640+
}
641+
642+
extension Header: BinaryParseKit.Parsable {
643+
init(parsing span: inout BinaryParsing.ParserSpan) throws(BinaryParsing.ThrownParsingError) {
644+
// Parse `a` of type Int
645+
BinaryParseKit.__assertParsable((Int).self)
646+
self.a = try Int(parsing: &span)
647+
// Parse `b` of type Int
648+
BinaryParseKit.__assertParsable((Int).self)
649+
self.b = try Int(parsing: &span)
650+
// Parse `c` of type Int
651+
BinaryParseKit.__assertParsable((Int).self)
652+
self.c = try Int(parsing: &span)
653+
}
654+
}
655+
""")
656+
}
614657
}
615658
}
616659

Tests/BinaryParseKitMacroTests/Misc.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import Testing
1616
#if canImport(BinaryParseKitMacros)
1717
import BinaryParseKitMacros
1818

19-
private nonisolated(unsafe) let testMacros: [String: Macro.Type] = [
19+
private let testMacros: [String: Macro.Type] = [
2020
"ParseStruct": ConstructStructParseMacro.self,
2121
"parse": EmptyPeerMacro.self,
2222
"skip": EmptyPeerMacro.self,

0 commit comments

Comments
 (0)