Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,13 @@ extension DeclBuilder {
)
}

public var inheritedGlobalActorIsolation: AttributeSyntax? {
let globalActor: AttributeSyntax? = switch settings.globalActorIsolationPreference {
case .nonisolated:
nil
case let .isolated(globalActor):
"@\(globalActor)"
case .none:
basicDeclaration.globalActor?.trimmed
public var inheritedGlobalActorIsolation: GlobalActorIsolation? {
if let preferred = settings.preferredGlobalActorIsolation {
return preferred
}
return globalActor?.withTrailingSpace
if let inferredType = basicDeclaration.globalActor?.attributeName.trimmed {
return .isolated(trimmedType: inferredType)
}
return .nonisolated
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import SwiftSyntax
public struct DeclBuilderSettings {

public var accessControlLevel: AccessControlLevel
public var globalActorIsolationPreference: GlobalActorIsolationPreference?
public var preferredGlobalActorIsolation: GlobalActorIsolation?

public init(
accessControlLevel: AccessControlLevel,
globalActorIsolationPreference: GlobalActorIsolationPreference? = nil
preferredGlobalActorIsolation: GlobalActorIsolation? = nil
) {
self.accessControlLevel = accessControlLevel
self.globalActorIsolationPreference = globalActorIsolationPreference
self.preferredGlobalActorIsolation = preferredGlobalActorIsolation
}
}

Expand Down
8 changes: 4 additions & 4 deletions Sources/PrincipleMacros/Parameters/ParameterExtractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ public struct ParameterExtractor {
return rawString
}

public func globalActorIsolationPreference(
public func preferredGlobalActorIsolation(
withLabel label: TokenSyntax?
) throws -> GlobalActorIsolationPreference? {
) throws -> GlobalActorIsolation? {
guard let expression = expression(withLabel: label) else {
return nil
}
Expand All @@ -77,8 +77,8 @@ public struct ParameterExtractor {

if let memberAccessExpression = MemberAccessExprSyntax(expression),
memberAccessExpression.declName.baseName.tokenKind == .keyword(.self),
let baseType = memberAccessExpression.base {
return .isolated("\(baseType)")
let explicitType = memberAccessExpression.base?.trimmed {
return .isolated(trimmedType: "\(explicitType)")
}

throw ParameterExtractionError.unexpectedSyntaxType
Expand Down
33 changes: 33 additions & 0 deletions Sources/PrincipleMacros/Syntax/Helpers/GlobalActorIsolation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// GlobalActorIsolation.swift
// PrincipleMacros
//
// Created by Kamil Strzelecki on 18/08/2025.
// Copyright © 2025 Kamil Strzelecki. All rights reserved.
//

import SwiftSyntax

public enum GlobalActorIsolation: Hashable {

case nonisolated
case isolated(trimmedType: TypeSyntax)

public var trimmedType: TypeSyntax? {
switch self {
case let .isolated(type):
type
case .nonisolated:
nil
}
}

public var trimmedAttribute: AttributeSyntax? {
guard let trimmedType else {
return nil
}
return AttributeSyntax(
attributeName: trimmedType
)
}
}

This file was deleted.

30 changes: 11 additions & 19 deletions Tests/PrincipleMacrosTests/Parameters/ParameterExtractorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,14 @@
func testTrailingClosureExtraction() throws {
let extractor = try makeExtractor(from: "#MyMacro { _ in }")
let extracted = try extractor.trailingClosure(withLabel: "operation")
let expected: ExprSyntax = "{ _ in }"
#expect(extracted?.description == expected.description)
#expect(extracted?.description == "{ _ in }")
}

@Test
func testTrailingClosureReferenceExtraction() throws {
let extractor = try makeExtractor(from: "#MyMacro(operation: perform)")
let extracted = try extractor.trailingClosure(withLabel: "operation")
let expected: ExprSyntax = "perform"
#expect(extracted?.description == expected.description)
#expect(extracted?.description == "perform")
}
}

Expand All @@ -80,16 +78,16 @@
extension ParameterExtractorTests {

@Test
func testMissingGlobalActorPreferenceExtraction() throws {
func testMissingPreferredGlobalActorExtraction() throws {
let extractor = try makeExtractor(from: "#MyMacro()")
let extracted = try extractor.globalActorIsolationPreference(withLabel: "isolation")
let extracted = try extractor.preferredGlobalActorIsolation(withLabel: "isolation")
#expect(extracted == nil)
}

@Test
func testNonisolatedGlobalActorPreferenceExtraction() throws {
func testNonisolatedPreferredGlobalActorExtraction() throws {
let extractor = try makeExtractor(from: "#MyMacro(isolation: nil)")
let extracted = try extractor.globalActorIsolationPreference(withLabel: "isolation")
let extracted = try extractor.preferredGlobalActorIsolation(withLabel: "isolation")
#expect(extracted == .nonisolated)
}

Expand All @@ -99,23 +97,17 @@
"SomeType.SomeActor"
]
)
func testIsolatedGlobalActorPreferenceExtraction(isolation: String) throws {
func testIsolatedPreferredGlobalActorExtraction(isolation: String) throws {
let extractor = try makeExtractor(from: "#MyMacro(isolation: \(raw: isolation).self)")
let extracted = try extractor.globalActorIsolationPreference(withLabel: "isolation")

switch extracted {
case let .isolated(globalActor):
#expect(globalActor.description == isolation)
default:
Issue.record()
}
let extracted = try extractor.preferredGlobalActorIsolation(withLabel: "isolation")
#expect(extracted?.attribute?.description == "@\(isolation)")

Check failure on line 103 in Tests/PrincipleMacrosTests/Parameters/ParameterExtractorTests.swift

View workflow job for this annotation

GitHub Actions / build-and-test (tvos)

value of type 'GlobalActorIsolation' has no member 'attribute'

Check failure on line 103 in Tests/PrincipleMacrosTests/Parameters/ParameterExtractorTests.swift

View workflow job for this annotation

GitHub Actions / build-and-test (watchos)

value of type 'GlobalActorIsolation' has no member 'attribute'

Check failure on line 103 in Tests/PrincipleMacrosTests/Parameters/ParameterExtractorTests.swift

View workflow job for this annotation

GitHub Actions / build-and-test (maccatalyst)

value of type 'GlobalActorIsolation' has no member 'attribute'

Check failure on line 103 in Tests/PrincipleMacrosTests/Parameters/ParameterExtractorTests.swift

View workflow job for this annotation

GitHub Actions / build-and-test (ios)

value of type 'GlobalActorIsolation' has no member 'attribute'
}

@Test
func testUnexpectedSyntaxWhenPerformingGlobalActorPreferenceExtraction() throws {
func testUnexpectedSyntaxWhenPerformingPreferredGlobalActorExtraction() throws {
let extractor = try makeExtractor(from: #"#MyMacro(isolation: MainActor.Type)"#)
#expect(throws: ParameterExtractionError.unexpectedSyntaxType) {
try extractor.globalActorIsolationPreference(withLabel: "isolation")
try extractor.preferredGlobalActorIsolation(withLabel: "isolation")
}
}
}
Loading