Skip to content

Commit cf60e66

Browse files
committed
Layout bitmask parsing
1 parent aeffe94 commit cf60e66

File tree

6 files changed

+105
-1
lines changed

6 files changed

+105
-1
lines changed

Sources/BinaryParseKit/BinaryParseKit.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,3 +538,23 @@ public macro matchDefault() = #externalMacro(
538538
module: "BinaryParseKitMacros",
539539
type: "EmptyPeerMacro",
540540
)
541+
542+
// MARK: - Bitmask
543+
544+
@attached(peer)
545+
public macro mask(bitCount: Int) = #externalMacro(
546+
module: "BinaryParseKitMacros",
547+
type: "EmptyPeerMacro",
548+
)
549+
550+
@attached(peer)
551+
public macro mask() = #externalMacro(
552+
module: "BinaryParseKitMacros",
553+
type: "EmptyPeerMacro",
554+
)
555+
556+
@attached(extension, conformances: BinaryParseKit.Parsable, names: arbitrary)
557+
public macro ParseBitmask() = #externalMacro(
558+
module: "BinaryParseKitMacros",
559+
type: "ConstructParseBitmaskMacro",
560+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//
2+
// BitmaskParsable.swift
3+
// BinaryParseKit
4+
//
5+
// Created by Larry Zeng on 11/28/25.
6+
//
7+
8+
public protocol BitmaskParsable: Parsable {
9+
static var bitCount: Int { get }
10+
}

Sources/BinaryParseKitMacros/BinaryParseKitMacro.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ struct BinaryParseKitPlugin: CompilerPlugin {
77
EmptyPeerMacro.self,
88
ConstructStructParseMacro.self,
99
ConstructEnumParseMacro.self,
10+
ConstructParseBitmaskMacro.self,
1011
]
1112
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//
2+
// ConstructParseBitmaskMacro.swift
3+
// BinaryParseKit
4+
//
5+
// Created by Larry Zeng on 11/28/25.
6+
//
7+
import SwiftDiagnostics
8+
import SwiftSyntax
9+
import SwiftSyntaxMacros
10+
11+
enum ParseBitmaskMacroError: Error, DiagnosticMessage {
12+
case onlyStructsAreSupported
13+
14+
var message: String {
15+
switch self {
16+
case .onlyStructsAreSupported: "@ParseBitmask can only be applied to structs."
17+
}
18+
}
19+
20+
var diagnosticID: SwiftDiagnostics.MessageID {
21+
.init(
22+
domain: "observer.universe.BinaryParseKit.ParseBitmaskMacroError",
23+
id: "\(self)",
24+
)
25+
}
26+
27+
var severity: SwiftDiagnostics.DiagnosticSeverity {
28+
switch self {
29+
case .onlyStructsAreSupported: .error
30+
}
31+
}
32+
}
33+
34+
public struct ConstructParseBitmaskMacro: ExtensionMacro {
35+
public static func expansion(
36+
of node: SwiftSyntax.AttributeSyntax,
37+
attachedTo declaration: some SwiftSyntax.DeclGroupSyntax,
38+
providingExtensionsOf type: some SwiftSyntax.TypeSyntaxProtocol,
39+
conformingTo _: [SwiftSyntax.TypeSyntax],
40+
in context: some SwiftSyntaxMacros.MacroExpansionContext,
41+
) throws -> [SwiftSyntax.ExtensionDeclSyntax] {
42+
guard let structDeclaration = declaration.as(StructDeclSyntax.self) else {
43+
throw ParseBitmaskMacroError.onlyStructsAreSupported
44+
}
45+
46+
let type = type.trimmed
47+
48+
let accessorInfo = try extractAccessor(
49+
from: node,
50+
attachedTo: declaration,
51+
in: context,
52+
)
53+
54+
// extract mask macro info
55+
56+
let bitmaskParsableExtension =
57+
try ExtensionDeclSyntax("extension \(type): \(raw: Constants.Protocols.bitmaskParsableProtocol)") {
58+
try VariableDeclSyntax("static var bitCount: Int") {
59+
#"fatalError("TODO")"#
60+
}
61+
62+
// FIXME: accessors
63+
try InitializerDeclSyntax(
64+
"\(accessorInfo.parsingAccessor) init(parsing span: inout \(raw: Constants.BinaryParsing.parserSpan)) throws(\(raw: Constants.BinaryParsing.thrownParsingError))",
65+
) {
66+
#"fatalError("TODO")"#
67+
}
68+
}
69+
70+
return [bitmaskParsableExtension]
71+
}
72+
}

Sources/BinaryParseKitMacros/Macros/Supports/Constants.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extension Constants {
3535
static let expressibleByParsingProtocol = PackageMember(name: "ExpressibleByParsing")
3636
static let matchableProtocol = PackageMember(name: "Matchable")
3737
static let printableProtocol = PackageMember(name: "Printable")
38+
static let bitmaskParsableProtocol = PackageMember(name: "BitmaskParsable")
3839
}
3940
}
4041

Sources/BinaryParseKitMacros/Macros/Supports/MacroAccessorVisitor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ enum MacroAccessorError: DiagnosticMessage, Error {
2828

2929
var diagnosticID: SwiftDiagnostics.MessageID {
3030
.init(
31-
domain: "BinaryParseKit.MacroACLError",
31+
domain: "observer.universe.BinaryParseKit.MacroACLError",
3232
id: "\(self)",
3333
)
3434
}

0 commit comments

Comments
 (0)