Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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 inferred = basicDeclaration.globalActor?.attributeName {
return .isolated(inferred)
}
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 globalActor = memberAccessExpression.base?.trimmed {
return .isolated("\(globalActor)")
}

throw ParameterExtractionError.unexpectedSyntaxType
Expand Down
31 changes: 31 additions & 0 deletions Sources/PrincipleMacros/Syntax/Helpers/GlobalActorIsolation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// 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(TypeSyntax)

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

public var attribute: AttributeSyntax? {
guard let type else {
return nil
}
return AttributeSyntax(attributeName: type)
}
}

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 @@ extension ParameterExtractorTests {
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 {
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 @@ extension ParameterExtractorTests {
"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)")
}

@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