-
Notifications
You must be signed in to change notification settings - Fork 0
Added superclass inference #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0d9af5d
d1012f1
c0cdfaf
5f93e9b
77acc75
0495316
b218f68
3823d0a
a9d5ff6
4d47af1
6f59de2
87bf3bd
b519312
ed34e2b
40f666c
600d256
2dc4d9b
d252434
a37ce11
39bedd1
58d9aa7
9d7a483
a7567a0
46b1776
ea7344a
cd74d85
8cf6797
b2ac2d1
514fa36
3e565d4
310be1b
cea794f
82a1709
c794584
dd5d1aa
4d647d5
bad8a9f
906bd5f
26a5f14
0f7a856
1f5fd7f
a1a517f
78f41cf
4715a6a
fef7ff9
b6753bb
2fb77b4
003b250
4d154d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,7 @@ on: | |
| - '*' | ||
|
|
||
| env: | ||
| XCODE_VERSION: "26.1" | ||
| XCODE_VERSION: "26.0" | ||
|
|
||
| jobs: | ||
| release: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // | ||
| // PropertyDeclAccessorBuilder.swift | ||
| // PrincipleMacros | ||
| // | ||
| // Created by Kamil Strzelecki on 28/11/2025. | ||
| // Copyright © 2025 Kamil Strzelecki. All rights reserved. | ||
| // | ||
|
|
||
| import SwiftSyntaxMacros | ||
|
|
||
| public protocol PropertyDeclAccessorBuilder: PropertyDeclBuilder { | ||
|
|
||
| func buildAccessors() throws -> [AccessorDeclSyntax] | ||
| } | ||
|
|
||
| extension PropertyDeclAccessorBuilder { | ||
|
|
||
| public func build() throws -> [DeclSyntax] { | ||
| try buildAccessors().map(DeclSyntax.init) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // | ||
| // 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, | ||
| fixIts: [FixIt] = [] | ||
| ) { | ||
| let message = MacroExpansionErrorMessage(message) | ||
| let diagnostic = Diagnostic(node: node, message: message, fixIts: fixIts) | ||
| self.init(diagnostics: [diagnostic]) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -121,6 +121,32 @@ extension ParameterExtractor { | |
| } | ||
| } | ||
|
|
||
| extension ParameterExtractor { | ||
|
|
||
| public func rawBool( | ||
| withLabel label: TokenSyntax? | ||
| ) throws -> Bool? { | ||
| guard let expression = expression(withLabel: label) else { | ||
| return nil | ||
| } | ||
|
|
||
| guard let bool = expression.as(BooleanLiteralExprSyntax.self) else { | ||
| throw ParameterExtractionError.unexpectedSyntaxType | ||
| } | ||
|
|
||
| return bool.literal.tokenKind == .keyword(.true) | ||
| } | ||
|
|
||
| public func requiredRawBool( | ||
| withLabel label: TokenSyntax? | ||
| ) throws -> Bool { | ||
| guard let bool = try rawBool(withLabel: label) else { | ||
| throw ParameterExtractionError.missingRequirement | ||
| } | ||
| return bool | ||
| } | ||
| } | ||
|
|
||
| extension ParameterExtractor { | ||
|
|
||
| public func rawString( | ||
|
|
@@ -160,18 +186,20 @@ extension ParameterExtractor { | |
| return nil | ||
| } | ||
|
|
||
| if NilLiteralExprSyntax(expression) != nil { | ||
| if expression.is(NilLiteralExprSyntax.self) { | ||
| let isolation = DeclModifierSyntax(name: .keyword(.nonisolated)) | ||
| return .nonisolated(trimmedModifer: isolation) | ||
| } | ||
|
|
||
| if let memberAccessExpression = MemberAccessExprSyntax(expression), | ||
| let explicitType = memberAccessExpression.base?.inferredType, | ||
| memberAccessExpression.referencesBaseType { | ||
| return .isolated(standardizedType: explicitType.standardized) | ||
| guard let memberAccessExpression = MemberAccessExprSyntax(expression), | ||
| let globalActorType = memberAccessExpression.baseTypeReference | ||
| else { | ||
| throw ParameterExtractionError.unexpectedSyntaxType | ||
| } | ||
|
|
||
| throw ParameterExtractionError.unexpectedSyntaxType | ||
| return .isolated( | ||
| standardizedType: globalActorType.standardized | ||
| ) | ||
| } | ||
|
|
||
| public func requiredGlobalActorIsolation( | ||
|
|
@@ -183,3 +211,31 @@ extension ParameterExtractor { | |
| return isolation | ||
| } | ||
| } | ||
|
|
||
| extension ParameterExtractor { | ||
|
|
||
| public func type( | ||
| withLabel label: TokenSyntax? | ||
| ) throws -> TypeSyntax? { | ||
| guard let expression = expression(withLabel: label) else { | ||
| return nil | ||
| } | ||
|
|
||
| guard let memberAccessExpression = MemberAccessExprSyntax(expression), | ||
| let type = memberAccessExpression.baseTypeReference | ||
| else { | ||
| throw ParameterExtractionError.unexpectedSyntaxType | ||
| } | ||
|
|
||
| return type | ||
| } | ||
|
|
||
| public func requiredType( | ||
| withLabel label: TokenSyntax? | ||
| ) throws -> TypeSyntax { | ||
| guard let type = try type(withLabel: label) else { | ||
| throw ParameterExtractionError.missingRequirement | ||
| } | ||
| return type | ||
| } | ||
|
Comment on lines
+217
to
+240
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Add documentation for public API methods. These new public methods lack doc comments explaining their purpose, parameters, return values, and error conditions. Since they're part of the public API, documentation would improve discoverability and usage. Consider adding documentation like: /// Extracts a type from a labeled expression of the form `Type.self`.
///
/// - Parameter label: The label of the parameter to extract, or `nil` for unlabeled parameters.
/// - Returns: The extracted type syntax, or `nil` if no expression with the given label exists.
/// - Throws: `ParameterExtractionError.unexpectedSyntaxType` if the expression is not a member access with a base type reference.
public func type(
withLabel label: TokenSyntax?
) throws -> TypeSyntax? {🤖 Prompt for AI Agents |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainParser helpers for declarations, members, and if-configs are well factored — verify conformers’ signatures The new One thing to double-check is that every 🏁 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*->' SourcesLength 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:' SourcesLength 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:' SourcesLength 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.swiftLength of output: 463 EnumCasesParser.parse(declaration:) must be updated to match the new The Parser protocol now requires public static func parse(declaration: some DeclSyntaxProtocol) throws -> EnumCasesList🤖 Prompt for AI Agents |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: NSFatalError/PrincipleMacros
Length of output: 302
🏁 Script executed:
Repository: NSFatalError/PrincipleMacros
Length of output: 1348
🏁 Script executed:
Repository: NSFatalError/PrincipleMacros
Length of output: 3443
🏁 Script executed:
Repository: NSFatalError/PrincipleMacros
Length of output: 2020
🏁 Script executed:
Repository: NSFatalError/PrincipleMacros
Length of output: 1210
🏁 Script executed:
Repository: NSFatalError/PrincipleMacros
Length of output: 2450
🏁 Script executed:
Repository: NSFatalError/PrincipleMacros
Length of output: 242
🏁 Script executed:
Repository: NSFatalError/PrincipleMacros
Length of output: 1978
🏁 Script executed:
Repository: NSFatalError/PrincipleMacros
Length of output: 2450
🏁 Script executed:
Repository: NSFatalError/PrincipleMacros
Length of output: 54
🌐 Web query:
SwiftSyntax 602.0.0 AccessorDeclSyntax DeclSyntax type conversion💡 Result:
Short answer: AccessorDeclSyntax is not a DeclSyntax (and cannot be implicitly converted to one). In SwiftSyntax 602 you must produce an AccessorDeclSyntax value when an AccessorMacro expects [AccessorDeclSyntax] — returning a DeclSyntax (or trying to cast an AccessorDeclSyntax to DeclSyntax) will fail.
Why: AccessorDeclSyntax represents accessor nodes (get/set/willSet/didSet) and conforms to SyntaxProtocol / AccessorDeclSyntaxProtocol, but it is not a DeclSyntax node (DeclSyntax represents top‑level/peer declarations). The macro APIs differentiate these types, so the compiler enforces returning the exact accessor type for AccessorMacro. Evidence and discussion in the Swift forums shows this exact error when a macro returned DeclSyntax instead of AccessorDeclSyntax. [1][3]
What to do:
Sources:
If you want, paste the code that fails and I’ll show the minimal change to return a proper AccessorDeclSyntax.
AccessorDeclSyntax cannot be converted to DeclSyntax—this code will not compile.
In SwiftSyntax 602.0.0,
AccessorDeclSyntaxandDeclSyntaxare distinct, non-convertible types.AccessorDeclSyntaxrepresents accessor nodes (get, set, willSet, didSet) that conform toSyntaxProtocol, whileDeclSyntaxrepresents top-level declarations. The mapping at line 19 attempting to convert[AccessorDeclSyntax]to[DeclSyntax]viaDeclSyntax.initwill result in a compiler error.The
build()method signature declares a return type of[DeclSyntax], butbuildAccessors()produces[AccessorDeclSyntax]. Either:build()return type to[AccessorDeclSyntax]if the intent is to return accessors, orbuild()to construct actual declarations (e.g.,VariableDeclSyntax) containing the accessors in anAccessorBlockSyntax.🤖 Prompt for AI Agents