Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
0d9af5d
-
NSFatalError Nov 21, 2025
d1012f1
-
NSFatalError Nov 21, 2025
c0cdfaf
[SwiftFormat] Applied formatting
NSFatalError Nov 21, 2025
5f93e9b
-
NSFatalError Nov 21, 2025
77acc75
-
NSFatalError Nov 21, 2025
0495316
-
NSFatalError Nov 21, 2025
b218f68
[SwiftFormat] Applied formatting
NSFatalError Nov 21, 2025
3823d0a
-
NSFatalError Nov 21, 2025
a9d5ff6
[SwiftFormat] Applied formatting
NSFatalError Nov 21, 2025
4d47af1
-
NSFatalError Nov 21, 2025
6f59de2
-
NSFatalError Nov 21, 2025
87bf3bd
-
NSFatalError Nov 21, 2025
b519312
-
NSFatalError Nov 21, 2025
ed34e2b
-
NSFatalError Nov 22, 2025
40f666c
-
NSFatalError Nov 22, 2025
600d256
[SwiftFormat] Applied formatting
NSFatalError Nov 22, 2025
2dc4d9b
-
NSFatalError Nov 22, 2025
d252434
-
NSFatalError Nov 22, 2025
a37ce11
[SwiftFormat] Applied formatting
NSFatalError Nov 22, 2025
39bedd1
-
NSFatalError Nov 22, 2025
58d9aa7
-
NSFatalError Nov 22, 2025
9d7a483
-
NSFatalError Nov 22, 2025
a7567a0
-
NSFatalError Nov 23, 2025
46b1776
-
NSFatalError Nov 23, 2025
ea7344a
-
NSFatalError Nov 23, 2025
cd74d85
-
NSFatalError Nov 23, 2025
8cf6797
-
NSFatalError Nov 23, 2025
b2ac2d1
-
NSFatalError Nov 23, 2025
514fa36
-
NSFatalError Nov 23, 2025
3e565d4
-
NSFatalError Nov 23, 2025
310be1b
-
NSFatalError Nov 23, 2025
cea794f
-
NSFatalError Nov 23, 2025
82a1709
-
NSFatalError Nov 23, 2025
c794584
-
NSFatalError Nov 23, 2025
dd5d1aa
-
NSFatalError Nov 23, 2025
4d647d5
-
NSFatalError Nov 23, 2025
bad8a9f
-
NSFatalError Nov 23, 2025
906bd5f
-
NSFatalError Nov 23, 2025
26a5f14
-
NSFatalError Nov 23, 2025
0f7a856
-
NSFatalError Nov 28, 2025
1f5fd7f
-
NSFatalError Nov 28, 2025
a1a517f
-
NSFatalError Nov 28, 2025
78f41cf
[SwiftFormat] Applied formatting
NSFatalError Nov 28, 2025
4715a6a
-
NSFatalError Nov 28, 2025
fef7ff9
-
NSFatalError Nov 28, 2025
b6753bb
-
NSFatalError Nov 28, 2025
2fb77b4
-
NSFatalError Nov 29, 2025
003b250
-
NSFatalError Nov 29, 2025
4d154d0
-
NSFatalError Nov 29, 2025
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
21 changes: 21 additions & 0 deletions Sources/PrincipleMacros/Diagnostics/DiagnosticsError.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// DiagnosticsError.swift
// PrincipleMacros
//
// Created by Kamil Strzelecki on 21/11/2025.
// Copyright © 2025 Kamil Strzelecki. All rights reserved.
//

import SwiftSyntaxMacros

extension DiagnosticsError {

public init(
node: some SyntaxProtocol,
message: String
) {
let message = MacroExpansionErrorMessage(message)
let diagnostic = Diagnostic(node: node, message: message)
self.init(diagnostics: [diagnostic])
}
}
46 changes: 39 additions & 7 deletions Sources/PrincipleMacros/Parsers/Common/Parser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,44 @@ public protocol Parser {
associatedtype ResultsCollection: ParserResultsCollection

static func parse(
declaration: some DeclSyntaxProtocol,
in context: some MacroExpansionContext
) -> ResultsCollection
declaration: some DeclSyntaxProtocol
) throws -> ResultsCollection
}

static func parse(
memberBlock: MemberBlockSyntax,
in context: some MacroExpansionContext
) -> ResultsCollection
extension Parser {

public static func parse(
ifConfig: IfConfigDeclSyntax
) throws -> ResultsCollection {
try ResultsCollection(
ifConfig.clauses.flatMap { clause in
switch clause.elements {
case let .decls(members):
try parse(members: members)
default:
ResultsCollection()
}
}
)
}

public static func parse(
members: MemberBlockItemListSyntax
) throws -> ResultsCollection {
try ResultsCollection(
members.flatMap { member in
if let ifConfig = member.decl.as(IfConfigDeclSyntax.self) {
try parse(ifConfig: ifConfig)
} else {
try parse(declaration: member.decl)
}
}
)
}

public static func parse(
memberBlock: MemberBlockSyntax
) throws -> ResultsCollection {
try parse(members: memberBlock.members)
}
Comment on lines 15 to +55
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Parser helpers for declarations, members, and if-configs are well factored — verify conformers’ signatures

The new throws-based Parser.parse(declaration:) requirement and the added parse(ifConfig:), parse(members:), and parse(memberBlock:) helpers give a clear, reusable traversal story for members and nested #if blocks. The flat-mapping of per-clause/per-member ResultsCollections into a single ResultsCollection matches the existing collection design.

One thing to double-check is that every Parser conformer’s parse(declaration:) implementation and all call sites have been updated to the new throws signature where appropriate.


🏁 Script executed:

#!/bin/bash
# Find non-throwing parse(declaration:) implementations that may need updating.
rg -nP 'static\s+func\s+parse\(\s*declaration:\s*some\s+DeclSyntaxProtocol\s*\)\s*->' Sources

Length of output: 0



🏁 Script executed:

#!/bin/bash
# Find the Parser protocol definition and all conformers
echo "=== Finding Parser protocol definition ==="
rg -nA5 'protocol\s+Parser' Sources

echo ""
echo "=== Finding types that conform to Parser ==="
rg -nP '\b(struct|class|enum)\s+\w+.*Parser\b' Sources

echo ""
echo "=== Finding all parse\(declaration: signatures (simplified) ==="
rg -nP 'parse\s*\(\s*declaration:' Sources

Length of output: 2102


🏁 Script executed:

#!/bin/bash
# Find the Parser protocol definition and all conformers
echo "=== Finding Parser protocol definition ==="
rg -nA5 'protocol\s+Parser' Sources

echo ""
echo "=== Finding types that conform to Parser ==="
rg -nP '\b(struct|class|enum)\s+\w+.*Parser\b' Sources

echo ""
echo "=== Finding all parse\(declaration: signatures (simplified) ==="
rg -nP 'parse\s*\(\s*declaration:' Sources

Length of output: 2102


🏁 Script executed:

#!/bin/bash
# Check EnumCasesParser.parse(declaration:) signature
echo "=== EnumCasesParser.parse(declaration:) ==="
rg -nA3 'static\s+func\s+parse' Sources/PrincipleMacros/Parsers/EnumCases/EnumCasesParser.swift

echo ""
echo "=== PropertiesParser.parse(declaration:) ==="
rg -nA3 'static\s+func\s+parse' Sources/PrincipleMacros/Parsers/Properties/PropertiesParser.swift

Length of output: 463


EnumCasesParser.parse(declaration:) must be updated to match the new throws protocol requirement

The Parser protocol now requires parse(declaration:) to throw, but EnumCasesParser's implementation at Sources/PrincipleMacros/Parsers/EnumCases/EnumCasesParser.swift:13 is still missing the throws keyword. PropertiesParser was correctly updated, but EnumCasesParser was not. Update the signature to:

public static func parse(declaration: some DeclSyntaxProtocol) throws -> EnumCasesList
🤖 Prompt for AI Agents
Sources/PrincipleMacros/Parsers/EnumCases/EnumCasesParser.swift around line 13:
the parse(declaration:) implementation is missing the throws keyword and should
match the protocol; change the function signature to be public static func
parse(declaration: some DeclSyntaxProtocol) throws -> EnumCasesList and update
its body to propagate errors (use try where calling other throwing parsers) so
the implementation compiles against the protocol.

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ where Element: ParserResult {
associatedtype Element

var all: [Element] { get }

init(_ all: [Element])
}

extension ParserResultsCollection {
Expand All @@ -24,6 +26,10 @@ extension ParserResultsCollection {
all.endIndex
}

public init() {
self.init([])
}

public subscript(position: Int) -> Element {
all[position]
}
Expand Down
26 changes: 0 additions & 26 deletions Sources/PrincipleMacros/Parsers/Common/_Parser.swift

This file was deleted.

This file was deleted.

4 changes: 2 additions & 2 deletions Sources/PrincipleMacros/Parsers/EnumCases/EnumCasesList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@

import SwiftSyntaxMacros

public struct EnumCasesList: _ParserResultsCollection {
public struct EnumCasesList: ParserResultsCollection {

public let all: [EnumCase]

init(_ all: [EnumCase]) {
public init(_ all: [EnumCase]) {
self.all = all
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@

import SwiftSyntaxMacros

public enum EnumCasesParser: _Parser {
public enum EnumCasesParser: Parser {

public static func parse(
declaration: some DeclSyntaxProtocol,
in _: some MacroExpansionContext
declaration: some DeclSyntaxProtocol
) -> EnumCasesList {
guard let declaration = EnumCaseDeclSyntax(declaration) else {
return .init()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@

import SwiftSyntaxMacros

public struct PropertiesList: _ParserResultsCollection {
public struct PropertiesList: ParserResultsCollection {

public let all: [Property]

init(_ all: [Property]) {
public init(_ all: [Property]) {
self.all = all
}
}
Expand Down
19 changes: 8 additions & 11 deletions Sources/PrincipleMacros/Parsers/Properties/PropertiesParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,29 @@

import SwiftSyntaxMacros

public enum PropertiesParser: _Parser {
public enum PropertiesParser: Parser {

public static func parse(
declaration: some DeclSyntaxProtocol,
in context: some MacroExpansionContext
) -> PropertiesList {
declaration: some DeclSyntaxProtocol
) throws -> PropertiesList {
guard let declaration = VariableDeclSyntax(declaration) else {
return .init()
}

return PropertiesList(
return try PropertiesList(
declaration.bindings.compactMap { binding -> Property? in
guard let name = binding.name else {
context.diagnose(
throw DiagnosticsError(
node: declaration,
errorMessage: "Property cannot be parsed"
message: "Property cannot be parsed"
)
return nil
}

guard let inferredType = binding.inferredType else {
context.diagnose(
throw DiagnosticsError(
node: declaration,
errorMessage: "Type of property cannot be inferred - provide it explicitly"
message: "Type of property cannot be inferred - provide it explicitly"
)
return nil
}

return Property(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ public enum GlobalActorIsolation {
}

public var standardizedIsolationAttribute: AttributeSyntax? {
guard let standardizedIsolationType else {
return nil
if let standardizedIsolationType {
return AttributeSyntax(attributeName: standardizedIsolationType)
}
return AttributeSyntax(attributeName: standardizedIsolationType)
return nil
}
}

Expand Down

This file was deleted.

16 changes: 0 additions & 16 deletions Sources/PrincipleMacros/Syntax/Extensions/AttributeSyntax.swift

This file was deleted.

56 changes: 56 additions & 0 deletions Sources/PrincipleMacros/Syntax/Extensions/ClassDeclSyntax.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// ClassDeclSyntax.swift
// PrincipleMacros
//
// Created by Kamil Strzelecki on 21/11/2025.
// Copyright © 2025 Kamil Strzelecki. All rights reserved.
//

import SwiftSyntaxMacros

extension ClassDeclSyntax {

public func inferredSuperclass() -> TypeSyntax? {
let superclassFinder = SuperclassFinder(for: self)
return superclassFinder.find()?.trimmed
}
}

extension ClassDeclSyntax {

private final class SuperclassFinder: SyntaxVisitor {

private let classDecl: ClassDeclSyntax
private var didFind = false

init(for classDecl: ClassDeclSyntax) {
self.classDecl = classDecl
super.init(viewMode: .sourceAccurate)
}

func find() -> TypeSyntax? {
guard let inheritanceClause = classDecl.inheritanceClause,
let firstInheritedType = inheritanceClause.inheritedTypes.first?.type
else {
return nil
}

walk(classDecl)
return didFind ? firstInheritedType : nil
}

override func visit(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind {
node == classDecl ? .visitChildren : .skipChildren
}

override func visit(_ node: DeclModifierSyntax) -> SyntaxVisitorContinueKind {
didFind = didFind || node.overrideSpecifier != nil
return .visitChildren
}

override func visit(_: SuperExprSyntax) -> SyntaxVisitorContinueKind {
didFind = true
return .visitChildren
}
}
}
16 changes: 10 additions & 6 deletions Sources/PrincipleMacros/Syntax/Extensions/ExprSyntax.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,14 @@ extension StringLiteralExprSyntax {
extension OptionalChainingExprSyntax {

public var inferredType: TypeSyntax? {
guard let inferredType = expression.inferredType else {
guard let inferredWrappedType else {
return nil
}
return "Optional<\(inferredType)>"
return "Optional<\(inferredWrappedType)>"
}

public var inferredWrappedType: TypeSyntax? {
expression.inferredType
}
}

Expand Down Expand Up @@ -134,10 +138,6 @@ extension GenericSpecializationExprSyntax {

extension MemberAccessExprSyntax {

public var referencesBaseType: Bool {
declName.baseName.tokenKind == .keyword(.self)
}

public var inferredType: TypeSyntax? {
guard let first = base?.inferredType else {
return nil
Expand All @@ -147,6 +147,10 @@ extension MemberAccessExprSyntax {
}
return first
}

public var referencesBaseType: Bool {
declName.baseName.tokenKind == .keyword(.self)
}
}

extension DeclReferenceExprSyntax {
Expand Down
Loading
Loading