diff --git a/Package.swift b/Package.swift index ca94fe5..f1efe00 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.1 +// swift-tools-version: 6.0 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription @@ -6,12 +6,12 @@ import PackageDescription let package = Package( name: "PrincipleMacros", platforms: [ - .macOS(.v15), - .macCatalyst(.v18), - .iOS(.v18), - .tvOS(.v18), - .watchOS(.v11), - .visionOS(.v2) + .macOS(.v14), + .macCatalyst(.v17), + .iOS(.v17), + .tvOS(.v17), + .watchOS(.v10), + .visionOS(.v1) ], products: [ .library( diff --git a/Sources/PrincipleMacros/Parsers/Properties/PropertiesList.swift b/Sources/PrincipleMacros/Parsers/Properties/PropertiesList.swift index 0c12ca0..d996294 100644 --- a/Sources/PrincipleMacros/Parsers/Properties/PropertiesList.swift +++ b/Sources/PrincipleMacros/Parsers/Properties/PropertiesList.swift @@ -46,6 +46,19 @@ extension PropertiesList { extension PropertiesList { + public var uniqueInferredTypes: [TypeSyntax] { + let allInferredTypes = all.lazy.map { property in + (property.inferredType.description, property.inferredType) + } + let dictionary = Dictionary( + allInferredTypes, + uniquingKeysWith: { first, _ in first } + ) + return dictionary.values.sorted { lhs, rhs in + lhs.description < rhs.description + } + } + public func withInferredType(like someType: TypeSyntax) -> Self { .init(filter { $0.inferredType.isLike(someType) }) } diff --git a/Sources/PrincipleMacros/Syntax/Extensions/TypeSyntax.swift b/Sources/PrincipleMacros/Syntax/Extensions/TypeSyntax.swift index 955bfb7..d588ccc 100644 --- a/Sources/PrincipleMacros/Syntax/Extensions/TypeSyntax.swift +++ b/Sources/PrincipleMacros/Syntax/Extensions/TypeSyntax.swift @@ -11,7 +11,7 @@ import SwiftSyntax extension TypeSyntax { public func isLike(_ other: TypeSyntax) -> Bool { - trimmedDescription == other.trimmedDescription + standardized.trimmedDescription == other.standardized.trimmedDescription } } diff --git a/Tests/PrincipleMacrosTests/Parsers/PropertiesListTests.swift b/Tests/PrincipleMacrosTests/Parsers/PropertiesListTests.swift new file mode 100644 index 0000000..a7808f1 --- /dev/null +++ b/Tests/PrincipleMacrosTests/Parsers/PropertiesListTests.swift @@ -0,0 +1,143 @@ +// +// PropertiesListTests.swift +// PrincipleMacros +// +// Created by Kamil Strzelecki on 15/05/2025. +// Copyright © 2025 Kamil Strzelecki. All rights reserved. +// + +@testable import PrincipleMacros +import SwiftSyntaxMacroExpansion +import Testing + +internal struct PropertiesListTests { + + private let list: PropertiesList + + init() throws { + let decl: DeclSyntax = """ + class Test { + + let letProp: Int? = 0 + var varProp = "" + lazy var lazyVarProp = Optional.none + + static let staticLetProp = String(data: Data(), encoding: .utf8) + static var staticVarProp = Int?.some(0) + class var classVarProp: String { "" } + + var computedProp: Int? { 0 } + var computedSettableProp: Optional { + get { 0 } + set {} + } + } + """ + + let classDecl = try #require(ClassDeclSyntax(decl)) + let context = BasicMacroExpansionContext() + self.list = PropertiesParser.parse(memberBlock: classDecl.memberBlock, in: context) + } + + @Test + func testImmutable() throws { + #expect( + list.immutable.map(\.trimmedName.description) == [ + "letProp", + "staticLetProp", + "classVarProp", + "computedProp" + ] + ) + } + + @Test + func testMutable() throws { + #expect( + list.mutable.map(\.trimmedName.description) == [ + "varProp", + "lazyVarProp", + "staticVarProp", + "computedSettableProp" + ] + ) + } + + @Test + func testInstance() throws { + #expect( + list.instance.map(\.trimmedName.description) == [ + "letProp", + "varProp", + "lazyVarProp", + "computedProp", + "computedSettableProp" + ] + ) + } + + @Test + func testType() throws { + #expect( + list.type.map(\.trimmedName.description) == [ + "staticLetProp", + "staticVarProp", + "classVarProp" + ] + ) + } + + @Test + func testStored() throws { + #expect( + list.stored.map(\.trimmedName.description) == [ + "letProp", + "varProp", + "lazyVarProp", + "staticLetProp", + "staticVarProp" + ] + ) + } + + @Test + func testComputed() throws { + #expect( + list.computed.map(\.trimmedName.description) == [ + "classVarProp", + "computedProp", + "computedSettableProp" + ] + ) + } + + @Test + func testUniqueInferredTypes() throws { + #expect( + list.uniqueInferredTypes.map(\.description) == [ + "Optional", + "String" + ] + ) + } + + @Test + func testWithInferredType() throws { + #expect( + list.withInferredType(like: "Int?").map(\.trimmedName.description) == [ + "letProp", + "lazyVarProp", + "staticVarProp", + "computedProp", + "computedSettableProp" + ] + ) + #expect( + list.withInferredType(like: "String").map(\.trimmedName.description) == [ + "varProp", + "staticLetProp", + "classVarProp" + ] + ) + } +}