diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 16d5c4b7..80ffc84f 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -23,7 +23,25 @@ on: jobs: swift_tests_latest: - name: Latest Swift + name: Latest Swift (6.1) + runs-on: macos-15 + steps: + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: latest + - uses: actions/checkout@v3 + - uses: actions/cache@v3 + with: + path: .build + key: macos-latest-spm-${{ hashFiles('**/Package.resolved') }} + restore-keys: | + macos-latest-tests-spm- + - name: Build + run: swift build + - name: Run tests + run: swift test + swift_tests_600: + name: Swift 6.0 runs-on: macos-15 steps: - uses: maxim-lobanov/setup-xcode@v1 @@ -35,12 +53,12 @@ jobs: path: .build key: macos-latest-spm-${{ hashFiles('**/Package.resolved') }} restore-keys: | - macos-latest-spm- + macos-600-tests-spm- - name: Build run: swift build - name: Run tests run: swift test - swift_tests_previous: + swift_tests_510: name: Swift 5.10 runs-on: macos-14 steps: @@ -53,7 +71,9 @@ jobs: path: .build key: macos-14-swift-510-spm-${{ hashFiles('**/Package.resolved') }} restore-keys: | - macos-14-swift-510-spm- + macos-14-swift-510-tests-spm- + - name: Remove Resolved + run: rm -rf Package.resolved - name: Build run: swift build - name: Run tests @@ -78,7 +98,9 @@ jobs: path: .build key: ${{ matrix.os }}-${{ matrix.swift }}-spm-${{ hashFiles('**/Package.resolved') }} restore-keys: | - ${{ matrix.os }}-spm- + ${{ matrix.os }}-tests-spm- + - name: Remove Resolved + run: rm -rf Package.resolved - name: Build run: swift build - name: Run tests diff --git a/Package.resolved b/Package.resolved index f77382ea..db9989ff 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,4 +1,5 @@ { + "originHash" : "32be71fe074b39617009f0851e8d4608c0271562fc8eb32489db8d0cfa2d9582", "pins" : [ { "identity" : "spimanifest", @@ -14,8 +15,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/swiftlang/swift-syntax.git", "state" : { - "revision" : "0687f71944021d616d34d922343dcef086855920", - "version" : "600.0.1" + "revision" : "f99ae8aa18f0cf0d53481901f88a0991dc3bd4a2", + "version" : "601.0.1" } }, { @@ -23,10 +24,10 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/jpsim/Yams.git", "state" : { - "revision" : "3036ba9d69cf1fd04d433527bc339dc0dc75433d", - "version" : "5.1.3" + "revision" : "b4b8042411dc7bbb696300a34a4bf3ba1b7ad19b", + "version" : "5.3.1" } } ], - "version" : 2 + "version" : 3 } diff --git a/Package.swift b/Package.swift index 10965cde..75b6eb12 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.0 +// swift-tools-version: 6.1 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription @@ -20,7 +20,7 @@ let package = Package( ), ], dependencies: [ - .package(url: "https://github.com/swiftlang/swift-syntax.git", from: "600.0.1"), + .package(url: "https://github.com/swiftlang/swift-syntax.git", from: "601.0.1"), ], targets: [ .target( diff --git a/Package@swift-6.0.swift b/Package@swift-6.0.swift new file mode 100644 index 00000000..10965cde --- /dev/null +++ b/Package@swift-6.0.swift @@ -0,0 +1,51 @@ +// swift-tools-version: 6.0 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "SyntaxSparrow", + platforms: [ + .macOS(.v10_15), + .iOS(.v13), + .tvOS(.v13), + .watchOS(.v6), + .macCatalyst(.v13) + ], + products: [ + // Products define the executables and libraries a package produces, and make them visible to other packages. + .library( + name: "SyntaxSparrow", + targets: ["SyntaxSparrow"] + ), + ], + dependencies: [ + .package(url: "https://github.com/swiftlang/swift-syntax.git", from: "600.0.1"), + ], + targets: [ + .target( + name: "SyntaxSparrow", + dependencies: [ + .product(name: "SwiftSyntax", package: "swift-syntax"), + .product(name: "SwiftParser", package: "swift-syntax"), + ], + resources: [ + .copy("Resources/PrivacyInfo.xcprivacy") + ], + swiftSettings: [ + .swiftLanguageMode(.v6) + ] + ), + .testTarget( + name: "SyntaxSparrowTests", + dependencies: [ + "SyntaxSparrow", + ] + ), + ] +) + +// Supplementary +package.dependencies.append(contentsOf: [ + .package(url: "https://github.com/SwiftPackageIndex/SPIManifest.git", from: "0.12.0"), +]) diff --git a/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/VariableSemanticsResolver.swift b/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/VariableSemanticsResolver.swift index 285125ba..5264b7de 100644 --- a/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/VariableSemanticsResolver.swift +++ b/Sources/SyntaxSparrow/Internal/Resolvers/Declaration/VariableSemanticsResolver.swift @@ -116,6 +116,9 @@ struct VariableSemanticsResolver: SemanticsResolving { // Resolver accessors for assessment let accessors = resolveAccessors() let accessorKinds = accessors.compactMap(\.kind) + // Only getter accessors mean that there is no setters + guard accessorKinds != [.get] else { return false } + // General setter check let hasSetterAccessor = accessorKinds.contains(where: { [.set, .willSet, .didSet].contains($0) }) let hasEffectGetter = accessors.contains(where: { let hasSpecifier = ($0.effectSpecifiers?.throwsSpecifier != nil || $0.effectSpecifiers?.asyncSpecifier != nil) @@ -125,7 +128,7 @@ struct VariableSemanticsResolver: SemanticsResolving { guard !hasEffectGetter else { return false } // If setter exists in accessors can return true (usually protocol context or manually written will/did/set accessor). if hasSetterAccessor { return true } - // If no accessors, but a direct return/code block, can assume there is no setter + // If no accessors, but a direct return/code block, can assume there is no setter. (computed var) if accessors.isEmpty, resolveHasCodeBlockItems() { return false } // Otherwise if the keyword is not `let` (immutable) guard resolveKeyword() != "let" else { return false } diff --git a/Sources/SyntaxSparrow/Public/Semantics/Components/EntityType.swift b/Sources/SyntaxSparrow/Public/Semantics/Components/EntityType.swift index a9ea3985..f2122ac3 100644 --- a/Sources/SyntaxSparrow/Public/Semantics/Components/EntityType.swift +++ b/Sources/SyntaxSparrow/Public/Semantics/Components/EntityType.swift @@ -139,4 +139,16 @@ public enum EntityType: Equatable, Hashable, CustomStringConvertible { public init(_ typeSyntax: TypeSyntax) { self = EntityType.parseType(typeSyntax) } + + #if swift(>=6.1) + /// Creates a new ``SyntaxSparrow/EntityType`` instance from a `GenericArgumentSyntax.Argument` node. + public init(_ argument: GenericArgumentSyntax.Argument) { + switch argument { + case .type(let typeSyntax): + self = EntityType.parseType(typeSyntax) + default: + self = .empty + } + } + #endif } diff --git a/Tests/SyntaxSparrowTests/Declarations/VariableTests.swift b/Tests/SyntaxSparrowTests/Declarations/VariableTests.swift index a37c49a2..1f7a88c7 100644 --- a/Tests/SyntaxSparrowTests/Declarations/VariableTests.swift +++ b/Tests/SyntaxSparrowTests/Declarations/VariableTests.swift @@ -66,6 +66,24 @@ final class VariableTests: XCTestCase { XCTAssertFalse(variable.hasSetter) } + func test_variable_mutable_onlyGetter_willReturnFalseForHasSetter() { + let source = #""" + var name: String { + get { "test" } + } + var other: String { + "test" + } + """# + instanceUnderTest.updateToSource(source) + XCTAssertTrue(instanceUnderTest.isStale) + instanceUnderTest.collectChildren() + XCTAssertFalse(instanceUnderTest.isStale) + XCTAssertEqual(instanceUnderTest.variables.count, 2) + XCTAssertFalse(instanceUnderTest.variables[0].hasSetter) + XCTAssertFalse(instanceUnderTest.variables[1].hasSetter) + } + func test_variable_multiplePatternBindings_willResolveExpectedValues() { let source = #""" var firstName, lastName: String @@ -297,7 +315,7 @@ final class VariableTests: XCTestCase { XCTAssertFalse(instanceUnderTest.variables[4].isComputed) XCTAssertTrue(instanceUnderTest.variables[5].isComputed) XCTAssertTrue(instanceUnderTest.variables[6].isComputed) - XCTAssertFalse(instanceUnderTest.variables[7].isComputed) + XCTAssertTrue(instanceUnderTest.variables[7].isComputed) } func test_variable_hasSetterHelper_willResolveExpectedValues() {