diff --git a/Demo/Demo.xcodeproj/project.pbxproj b/Demo/Demo.xcodeproj/project.pbxproj index bf1e641..6b50c1b 100644 --- a/Demo/Demo.xcodeproj/project.pbxproj +++ b/Demo/Demo.xcodeproj/project.pbxproj @@ -3,28 +3,53 @@ archiveVersion = 1; classes = { }; - objectVersion = 77; + objectVersion = 63; objects = { /* Begin PBXBuildFile section */ + 0E18AC1B2EC0EA5E00BC420B /* HelloWorldView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC1C2EC0EA5E00BC420B /* HelloWorldView.swift */; }; + 0E18AC1D2EC0EA5E00BC420B /* StateManagementView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC1E2EC0EA5E00BC420B /* StateManagementView.swift */; }; + 0E18AC1F2EC0EA5E00BC420B /* UpdatingWithAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC202EC0EA5E00BC420B /* UpdatingWithAnimationView.swift */; }; + 0E18AC212EC0EA5E00BC420B /* BarsCardViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC222EC0EA5E00BC420B /* BarsCardViewCell.swift */; }; + 0E18AC232EC0EA5E00BC420B /* BarsListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC242EC0EA5E00BC420B /* BarsListViewController.swift */; }; + 0E18AC252EC0EA5E00BC420B /* BarsModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC262EC0EA5E00BC420B /* BarsModels.swift */; }; + 0E18AC272EC0EA5E00BC420B /* AlignmentGuidesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC282EC0EA5E00BC420B /* AlignmentGuidesView.swift */; }; + 0E18AC292EC0EA5E00BC420B /* CustomAlignmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC2A2EC0EA5E00BC420B /* CustomAlignmentView.swift */; }; + 0E18AC2B2EC0EA5E00BC420B /* EmojiAlignmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC2C2EC0EA5E00BC420B /* EmojiAlignmentView.swift */; }; + 0E18AC2D2EC0EA5E00BC420B /* FirstLabelAlignmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC2E2EC0EA5E00BC420B /* FirstLabelAlignmentView.swift */; }; + 0E18AC2F2EC0EA5E00BC420B /* FruitSelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC302EC0EA5E00BC420B /* FruitSelectorView.swift */; }; + 0E18AC312EC0EA5E00BC420B /* AdvanceSizingContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC322EC0EA5E00BC420B /* AdvanceSizingContainerView.swift */; }; + 0E18AC332EC0EA5E00BC420B /* AdvanceSizingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC342EC0EA5E00BC420B /* AdvanceSizingView.swift */; }; + 0E18AC352EC0EA5E00BC420B /* LazyInstantiationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC362EC0EA5E00BC420B /* LazyInstantiationView.swift */; }; + 0E18AC372EC0EA5E00BC420B /* MobileConfigMigrationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC382EC0EA5E00BC420B /* MobileConfigMigrationView.swift */; }; + 0E18AC392EC0EA5E00BC420B /* GridLayoutExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC3A2EC0EA5E00BC420B /* GridLayoutExampleView.swift */; }; + 0E18AC3B2EC0EA5E00BC420B /* QuickLayoutShowcaseApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E18AC3C2EC0EA5E00BC420B /* QuickLayoutShowcaseApp.swift */; }; 0E56B79C2EBCE521004F79FC /* QuickLayoutShowcaseAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E56B79B2EBCE521004F79FC /* QuickLayoutShowcaseAssets.xcassets */; }; 0E6E97342EB93FDF0030E0DA /* QuickLayout in Frameworks */ = {isa = PBXBuildFile; productRef = 0E6E97332EB93FDF0030E0DA /* QuickLayout */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 0E18AC1C2EC0EA5E00BC420B /* HelloWorldView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelloWorldView.swift; sourceTree = ""; }; + 0E18AC1E2EC0EA5E00BC420B /* StateManagementView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateManagementView.swift; sourceTree = ""; }; + 0E18AC202EC0EA5E00BC420B /* UpdatingWithAnimationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdatingWithAnimationView.swift; sourceTree = ""; }; + 0E18AC222EC0EA5E00BC420B /* BarsCardViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarsCardViewCell.swift; sourceTree = ""; }; + 0E18AC242EC0EA5E00BC420B /* BarsListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarsListViewController.swift; sourceTree = ""; }; + 0E18AC262EC0EA5E00BC420B /* BarsModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarsModels.swift; sourceTree = ""; }; + 0E18AC282EC0EA5E00BC420B /* AlignmentGuidesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlignmentGuidesView.swift; sourceTree = ""; }; + 0E18AC2A2EC0EA5E00BC420B /* CustomAlignmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomAlignmentView.swift; sourceTree = ""; }; + 0E18AC2C2EC0EA5E00BC420B /* EmojiAlignmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiAlignmentView.swift; sourceTree = ""; }; + 0E18AC2E2EC0EA5E00BC420B /* FirstLabelAlignmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstLabelAlignmentView.swift; sourceTree = ""; }; + 0E18AC302EC0EA5E00BC420B /* FruitSelectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FruitSelectorView.swift; sourceTree = ""; }; + 0E18AC322EC0EA5E00BC420B /* AdvanceSizingContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvanceSizingContainerView.swift; sourceTree = ""; }; + 0E18AC342EC0EA5E00BC420B /* AdvanceSizingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvanceSizingView.swift; sourceTree = ""; }; + 0E18AC362EC0EA5E00BC420B /* LazyInstantiationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyInstantiationView.swift; sourceTree = ""; }; + 0E18AC382EC0EA5E00BC420B /* MobileConfigMigrationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MobileConfigMigrationView.swift; sourceTree = ""; }; + 0E18AC3A2EC0EA5E00BC420B /* GridLayoutExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GridLayoutExampleView.swift; sourceTree = ""; }; + 0E18AC3C2EC0EA5E00BC420B /* QuickLayoutShowcaseApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickLayoutShowcaseApp.swift; sourceTree = ""; }; 0E56B79B2EBCE521004F79FC /* QuickLayoutShowcaseAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = QuickLayoutShowcaseAssets.xcassets; path = ../Sources/QuickLayout/QuickLayoutShowcaseAssets.xcassets; sourceTree = SOURCE_ROOT; }; 0E6E96F72EB93F9C0030E0DA /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ -/* Begin PBXFileSystemSynchronizedRootGroup section */ - 0E18AC1A2EC0EA5E00BC420B /* __showcase__ */ = { - isa = PBXFileSystemSynchronizedRootGroup; - name = __showcase__; - path = ../Sources/QuickLayout/QuickLayout/__showcase__; - sourceTree = SOURCE_ROOT; - }; -/* End PBXFileSystemSynchronizedRootGroup section */ - /* Begin PBXFrameworksBuildPhase section */ 0E6E96F42EB93F9C0030E0DA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; @@ -37,6 +62,103 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 0E18AC1A2EC0EA5E00BC420B /* __showcase__ */ = { + isa = PBXGroup; + children = ( + 0E18AC3C2EC0EA5E00BC420B /* QuickLayoutShowcaseApp.swift */, + 0E18AC1B2EC0EA5E00BC420C /* 1-HelloWorld */, + 0E18AC1D2EC0EA5E00BC420C /* 2-StateManagementView */, + 0E18AC1F2EC0EA5E00BC420C /* 3-Animations */, + 0E18AC212EC0EA5E00BC420C /* 4-ListExample */, + 0E18AC272EC0EA5E00BC420C /* 5-Alignment */, + 0E18AC312EC0EA5E00BC420C /* 6-AdvanceSizing */, + 0E18AC352EC0EA5E00BC420C /* 7-LazyView */, + 0E18AC372EC0EA5E00BC420C /* 8-MobileConfigMigrationView */, + 0E18AC392EC0EA5E00BC420C /* 9-LayoutContainers */, + ); + name = __showcase__; + path = ../Sources/QuickLayout/QuickLayout/__showcase__; + sourceTree = SOURCE_ROOT; + }; + 0E18AC1B2EC0EA5E00BC420C /* 1-HelloWorld */ = { + isa = PBXGroup; + children = ( + 0E18AC1C2EC0EA5E00BC420B /* HelloWorldView.swift */, + ); + path = "1-HelloWorld"; + sourceTree = ""; + }; + 0E18AC1D2EC0EA5E00BC420C /* 2-StateManagementView */ = { + isa = PBXGroup; + children = ( + 0E18AC1E2EC0EA5E00BC420B /* StateManagementView.swift */, + ); + path = "2-StateManagementView"; + sourceTree = ""; + }; + 0E18AC1F2EC0EA5E00BC420C /* 3-Animations */ = { + isa = PBXGroup; + children = ( + 0E18AC202EC0EA5E00BC420B /* UpdatingWithAnimationView.swift */, + ); + path = "3-Animations"; + sourceTree = ""; + }; + 0E18AC212EC0EA5E00BC420C /* 4-ListExample */ = { + isa = PBXGroup; + children = ( + 0E18AC222EC0EA5E00BC420B /* BarsCardViewCell.swift */, + 0E18AC242EC0EA5E00BC420B /* BarsListViewController.swift */, + 0E18AC262EC0EA5E00BC420B /* BarsModels.swift */, + ); + path = "4-ListExample"; + sourceTree = ""; + }; + 0E18AC272EC0EA5E00BC420C /* 5-Alignment */ = { + isa = PBXGroup; + children = ( + 0E18AC282EC0EA5E00BC420B /* AlignmentGuidesView.swift */, + 0E18AC2A2EC0EA5E00BC420B /* CustomAlignmentView.swift */, + 0E18AC2C2EC0EA5E00BC420B /* EmojiAlignmentView.swift */, + 0E18AC2E2EC0EA5E00BC420B /* FirstLabelAlignmentView.swift */, + 0E18AC302EC0EA5E00BC420B /* FruitSelectorView.swift */, + ); + path = "5-Alignment"; + sourceTree = ""; + }; + 0E18AC312EC0EA5E00BC420C /* 6-AdvanceSizing */ = { + isa = PBXGroup; + children = ( + 0E18AC322EC0EA5E00BC420B /* AdvanceSizingContainerView.swift */, + 0E18AC342EC0EA5E00BC420B /* AdvanceSizingView.swift */, + ); + path = "6-AdvanceSizing"; + sourceTree = ""; + }; + 0E18AC352EC0EA5E00BC420C /* 7-LazyView */ = { + isa = PBXGroup; + children = ( + 0E18AC362EC0EA5E00BC420B /* LazyInstantiationView.swift */, + ); + path = "7-LazyView"; + sourceTree = ""; + }; + 0E18AC372EC0EA5E00BC420C /* 8-MobileConfigMigrationView */ = { + isa = PBXGroup; + children = ( + 0E18AC382EC0EA5E00BC420B /* MobileConfigMigrationView.swift */, + ); + path = "8-MobileConfigMigrationView"; + sourceTree = ""; + }; + 0E18AC392EC0EA5E00BC420C /* 9-LayoutContainers */ = { + isa = PBXGroup; + children = ( + 0E18AC3A2EC0EA5E00BC420B /* GridLayoutExampleView.swift */, + ); + path = "9-LayoutContainers"; + sourceTree = ""; + }; 0E6E96EE2EB93F9C0030E0DA = { isa = PBXGroup; children = ( @@ -77,9 +199,6 @@ ); dependencies = ( ); - fileSystemSynchronizedGroups = ( - 0E18AC1A2EC0EA5E00BC420B /* __showcase__ */, - ); name = Demo; packageProductDependencies = ( 0E6E97332EB93FDF0030E0DA /* QuickLayout */, @@ -95,15 +214,16 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 2600; - LastUpgradeCheck = 2600; + LastSwiftUpdateCheck = 1540; + LastUpgradeCheck = 1540; TargetAttributes = { 0E6E96F62EB93F9C0030E0DA = { - CreatedOnToolsVersion = 26.0; + CreatedOnToolsVersion = 15.4; }; }; }; buildConfigurationList = 0E6E96F22EB93F9C0030E0DA /* Build configuration list for PBXProject "Demo" */; + compatibilityVersion = "Xcode 15.3"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -115,7 +235,6 @@ packageReferences = ( 0E6E97312EB93FCE0030E0DA /* XCLocalSwiftPackageReference "../" */, ); - preferredProjectObjectVersion = 77; productRefGroup = 0E6E96F82EB93F9C0030E0DA /* Products */; projectDirPath = ""; projectRoot = ""; @@ -141,6 +260,23 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0E18AC1B2EC0EA5E00BC420B /* HelloWorldView.swift in Sources */, + 0E18AC1D2EC0EA5E00BC420B /* StateManagementView.swift in Sources */, + 0E18AC1F2EC0EA5E00BC420B /* UpdatingWithAnimationView.swift in Sources */, + 0E18AC212EC0EA5E00BC420B /* BarsCardViewCell.swift in Sources */, + 0E18AC232EC0EA5E00BC420B /* BarsListViewController.swift in Sources */, + 0E18AC252EC0EA5E00BC420B /* BarsModels.swift in Sources */, + 0E18AC272EC0EA5E00BC420B /* AlignmentGuidesView.swift in Sources */, + 0E18AC292EC0EA5E00BC420B /* CustomAlignmentView.swift in Sources */, + 0E18AC2B2EC0EA5E00BC420B /* EmojiAlignmentView.swift in Sources */, + 0E18AC2D2EC0EA5E00BC420B /* FirstLabelAlignmentView.swift in Sources */, + 0E18AC2F2EC0EA5E00BC420B /* FruitSelectorView.swift in Sources */, + 0E18AC312EC0EA5E00BC420B /* AdvanceSizingContainerView.swift in Sources */, + 0E18AC332EC0EA5E00BC420B /* AdvanceSizingView.swift in Sources */, + 0E18AC352EC0EA5E00BC420B /* LazyInstantiationView.swift in Sources */, + 0E18AC372EC0EA5E00BC420B /* MobileConfigMigrationView.swift in Sources */, + 0E18AC392EC0EA5E00BC420B /* GridLayoutExampleView.swift in Sources */, + 0E18AC3B2EC0EA5E00BC420B /* QuickLayoutShowcaseApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -199,7 +335,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -256,7 +392,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; @@ -280,6 +416,7 @@ INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -288,10 +425,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.meta.SampleApp; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = YES; - SWIFT_APPROACHABLE_CONCURRENCY = YES; - SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -311,6 +445,7 @@ INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -319,10 +454,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.meta.SampleApp; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = YES; - SWIFT_APPROACHABLE_CONCURRENCY = YES; - SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; diff --git a/Package.swift b/Package.swift index e308ca1..3120d93 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.0 +// swift-tools-version: 5.9 // The swift-tools-version declares the minimum version of Swift required to build this package. /* * Copyright (c) Meta Platforms, Inc. and affiliates. @@ -21,28 +21,21 @@ let package = Package( name: "QuickLayout", targets: ["QuickLayout"] ), - .library( - name: "QuickLayoutCore", - targets: ["QuickLayoutCore"] - ), .library( name: "FastResultBuilder", targets: ["FastResultBuilder"] ), - .library( - name: "QuickLayoutBridge", - targets: ["QuickLayoutBridge"] - ), ], dependencies: [ - .package(url: "https://github.com/apple/swift-syntax.git", from: "600.0.0") + .package(url: "https://github.com/apple/swift-syntax.git", from: "602.0.0"), + .package(url: "https://github.com/pointfreeco/swift-macro-testing.git", from: "0.6.4"), ], targets: [ .target( name: "QuickLayout", dependencies: [ "QuickLayoutMacro", - "QuickLayoutBridge", + .target(name: "QuickLayoutBridge", condition: .when(platforms: [.iOS])), ], path: "Sources/QuickLayout/QuickLayout", exclude: [ @@ -55,11 +48,11 @@ let package = Package( .product(name: "SwiftSyntaxMacros", package: "swift-syntax"), .product(name: "SwiftCompilerPlugin", package: "swift-syntax"), ], - path: "Sources/QuickLayout/QuickLayoutMacro", + path: "Sources/QuickLayout/QuickLayoutMacro" ), .target( name: "QuickLayoutCore", - path: "Sources/QuickLayout/QuickLayoutCore", + path: "Sources/QuickLayout/QuickLayoutCore" ), .target( name: "FastResultBuilder", @@ -70,12 +63,33 @@ let package = Package( ), .target( name: "QuickLayoutBridge", - dependencies: ["FastResultBuilder", "QuickLayoutCore"], + dependencies: [ + "FastResultBuilder", + .target(name: "QuickLayoutCore", condition: .when(platforms: [.iOS])), + ], path: "Sources/QuickLayout/QuickLayoutBridge", exclude: [ "__server_snapshot_tests__", "__tests__", ] ), - ], + .testTarget( + name: "QuickLayoutMacroTests", + dependencies: [ + "QuickLayoutMacro", + .swiftSyntaxMacrosTestSupport, + ], + path: "Sources/QuickLayout/QuickLayoutMacroTests" + ) + ] ) + +extension Target.Dependency { + // swift-syntax + static let swiftSyntax = Self.product(name: "SwiftSyntax", package: "swift-syntax") + static let swiftSyntaxMacros = Self.product(name: "SwiftSyntaxMacros", package: "swift-syntax") + static let swiftCompilerPlugin = Self.product(name: "SwiftCompilerPlugin", package: "swift-syntax") + static let swiftSyntaxBuilder = Self.product(name: "SwiftSyntaxBuilder", package: "swift-syntax") + static let swiftParserDiagnostics = Self.product(name: "SwiftParserDiagnostics", package: "swift-syntax") + static let swiftSyntaxMacrosTestSupport = Self.product(name: "SwiftSyntaxMacrosTestSupport", package: "swift-syntax") +} diff --git a/Sources/QuickLayout/QuickLayout/QuickLayout.swift b/Sources/QuickLayout/QuickLayout/QuickLayout.swift index c9d63d9..cf4e5cf 100644 --- a/Sources/QuickLayout/QuickLayout/QuickLayout.swift +++ b/Sources/QuickLayout/QuickLayout/QuickLayout.swift @@ -5,4 +5,6 @@ * LICENSE file in the root directory of this source tree. */ +#if canImport(QuickLayoutBridge) @_exported import QuickLayoutBridge +#endif diff --git a/Sources/QuickLayout/QuickLayout/__showcase__/4-ListExample/BarsModels.swift b/Sources/QuickLayout/QuickLayout/__showcase__/4-ListExample/BarsModels.swift index 515f8f4..fd3a965 100644 --- a/Sources/QuickLayout/QuickLayout/__showcase__/4-ListExample/BarsModels.swift +++ b/Sources/QuickLayout/QuickLayout/__showcase__/4-ListExample/BarsModels.swift @@ -14,7 +14,11 @@ struct BarModel { let description: String let shareURL: URL } +#if compiler(>=6.1) nonisolated extension BarModel: Hashable {} +#else +extension BarModel: Hashable {} +#endif // swiftlint:disable force_unwrapping actor BarsStore { diff --git a/Sources/QuickLayout/QuickLayoutBridge/QuickLayout.swift b/Sources/QuickLayout/QuickLayoutBridge/QuickLayout.swift index f8e6c4c..28e7f3a 100644 --- a/Sources/QuickLayout/QuickLayoutBridge/QuickLayout.swift +++ b/Sources/QuickLayout/QuickLayoutBridge/QuickLayout.swift @@ -76,7 +76,7 @@ public func Grid( alignment: Alignment = .center, horizontalSpacing: CGFloat = 0, verticalSpacing: CGFloat = 0, - @FastArrayBuilder rows: () -> [GridRowElement] = { [] }, + @FastArrayBuilder rows: () -> [GridRowElement] = { [] } ) -> Element & Layout { GridElement(rows: rows(), alignment: alignment, horizontalSpacing: horizontalSpacing, verticalSpacing: verticalSpacing) } diff --git a/Sources/QuickLayout/QuickLayoutBridge/QuickLayoutMacroDeclaration.swift b/Sources/QuickLayout/QuickLayoutBridge/QuickLayoutMacroDeclaration.swift index 8a5c6e3..08225b0 100644 --- a/Sources/QuickLayout/QuickLayoutBridge/QuickLayoutMacroDeclaration.swift +++ b/Sources/QuickLayout/QuickLayoutBridge/QuickLayoutMacroDeclaration.swift @@ -17,8 +17,10 @@ @attached(extension, conformances: HasBody) public macro QuickLayout() = #externalMacro(module: "QuickLayoutMacro", type: "QuickLayout") +#if compiler(>=6) /** This macro is an implementation detail of @QuickLayout. It is not intended to be used directly. */ @attached(body) public macro _QuickLayoutInjection(_ value: String) = #externalMacro(module: "QuickLayoutMacro", type: "QuickLayoutInjection") +#endif diff --git a/Sources/QuickLayout/QuickLayoutBridge/ViewImplementation/BodyAppearanceCoordinator.swift b/Sources/QuickLayout/QuickLayoutBridge/ViewImplementation/BodyAppearanceCoordinator.swift index 983674f..f67291f 100644 --- a/Sources/QuickLayout/QuickLayoutBridge/ViewImplementation/BodyAppearanceCoordinator.swift +++ b/Sources/QuickLayout/QuickLayoutBridge/ViewImplementation/BodyAppearanceCoordinator.swift @@ -12,7 +12,7 @@ private let disappearanceAnimationKey = "BodyAppearanceCoordinator-disappearance private let disappearanceAnimationIDKey = "BodyAppearanceCoordinator-disappearance-id" @MainActor -final class BodyAppearanceCoordinator: NSObject, @preconcurrency CAAnimationDelegate { +final class BodyAppearanceCoordinator: NSObject { private var disappearanceAnimationID: Int = 0 private var appearingViews: Set = [] private var activeViews: Set = [] @@ -123,3 +123,9 @@ fileprivate extension UIView { animationKeys.forEach { layer.removeAnimation(forKey: $0) } } } + +#if compiler(>=6) +extension BodyAppearanceCoordinator: @preconcurrency CAAnimationDelegate {} +#else +extension BodyAppearanceCoordinator: CAAnimationDelegate {} +#endif diff --git a/Sources/QuickLayout/QuickLayoutCore/Element+UIKit.swift b/Sources/QuickLayout/QuickLayoutCore/Element+UIKit.swift index 0659b56..bbfd171 100644 --- a/Sources/QuickLayout/QuickLayoutCore/Element+UIKit.swift +++ b/Sources/QuickLayout/QuickLayoutCore/Element+UIKit.swift @@ -22,8 +22,13 @@ private func sanitizeSize(_ size: CGSize) -> CGSize { } // patternlint-disable-next-line retroactive-conformance-systemlib -extension UIView: @preconcurrency LeafElement { +#if compiler(>=6) +extension UIView: @preconcurrency LeafElement {} +#else +extension UIView: LeafElement {} +#endif +extension UIView { public func quick_layoutThatFits(_ proposedSize: CGSize) -> LayoutNode { assert(Thread.isMainThread, "UIViews can be laid out only on the main thread.") diff --git a/Sources/QuickLayout/QuickLayoutMacro/QuickLayout.swift b/Sources/QuickLayout/QuickLayoutMacro/QuickLayout.swift index 4eb4897..78b1287 100644 --- a/Sources/QuickLayout/QuickLayoutMacro/QuickLayout.swift +++ b/Sources/QuickLayout/QuickLayoutMacro/QuickLayout.swift @@ -7,6 +7,27 @@ import SwiftSyntax import SwiftSyntaxMacros +import SwiftDiagnostics +import Foundation + +enum QuickLayoutDiagnostic: DiagnosticMessage { + case missingRequiredImplementation(functionName: String, requiredCall: String) + + var message: String { + switch self { + case .missingRequiredImplementation(let functionName, let requiredCall): + return "Method '\(functionName)' is missing required implementation call. Below Swift 6.0, you must manually add the following call:\n\(requiredCall)" + } + } + + var diagnosticID: MessageID { + MessageID(domain: "QuickLayout", id: "missingRequiredImplementation") + } + + var severity: DiagnosticSeverity { + .error + } +} public struct QuickLayout: ExtensionMacro, MemberMacro, MemberAttributeMacro { // MARK: - ExtensionMacro @@ -63,7 +84,30 @@ public struct QuickLayout: ExtensionMacro, MemberMacro, MemberAttributeMacro { case .deferToProvidedDefinition: continue case .injectIntoProvidedDefinition(let impl): +#if compiler(>=6) return ["@_QuickLayoutInjection(\"\(raw: impl(memberFunction))\")"] +#else + // 在 Swift 6.0 以下,检查方法体中是否已包含必要的实现调用 + let requiredCall = impl(memberFunction) + let functionBody = memberFunction.body?.statements.description ?? "" + + // 检查方法体中是否包含必要的调用 + if (functionBody as NSString).contains(requiredCall) { + // 已经包含必要的实现,跳过 + continue + } else { + // 缺少必要的实现,抛出诊断错误 + let diagnostic = Diagnostic( + node: memberFunction, + message: QuickLayoutDiagnostic.missingRequiredImplementation( + functionName: memberFunction.name.text, + requiredCall: requiredCall + ) + ) + context.diagnose(diagnostic) + continue + } +#endif } } } else if let memberVariable = member.variable { diff --git a/Sources/QuickLayout/QuickLayoutMacroTests/QuickLayoutTests.swift b/Sources/QuickLayout/QuickLayoutMacroTests/QuickLayoutTests.swift index d090901..3ca63bd 100644 --- a/Sources/QuickLayout/QuickLayoutMacroTests/QuickLayoutTests.swift +++ b/Sources/QuickLayout/QuickLayoutMacroTests/QuickLayoutTests.swift @@ -5,10 +5,11 @@ * LICENSE file in the root directory of this source tree. */ -import QuickLayoutMacro import SwiftSyntaxMacros import SwiftSyntaxMacrosTestSupport import XCTest +#if canImport(QuickLayoutMacro) +@testable import QuickLayoutMacro // patternlint-disable meta-subclass-view @@ -117,6 +118,7 @@ class QuickLayoutTests: XCTestCase { } func testApplicableMethodsInjectQuickLayoutBridgeementation() throws { +#if compiler(>=6) assertMacroExpansion( #""" @QuickLayout @@ -171,6 +173,78 @@ class QuickLayoutTests: XCTestCase { macros: testMacros, indentationWidth: .spaces(2) ) +#else + assertMacroExpansion( + #""" + @QuickLayout + class TestView: UIView { + var body: Layout { + EmptyLayout() + } + + public override func willMove(toWindow newWindow: UIWindow?) { + super.willMove(toWindow: newWindow) + someUniqueWillMoveToWindowLogic() + } + + public override func layoutSubviews() { + super.layoutSubviews() + someUniqueLayoutSubviewsLogic() + } + } + """#, + expandedSource: + #""" + class TestView: UIView { + @LayoutBuilder + var body: Layout { + EmptyLayout() + } + + public override func willMove(toWindow newWindow: UIWindow?) { + super.willMove(toWindow: newWindow) + someUniqueWillMoveToWindowLogic() + } + + public override func layoutSubviews() { + super.layoutSubviews() + someUniqueLayoutSubviewsLogic() + } + + public override func sizeThatFits(_ size: CGSize) -> CGSize { + return _QuickLayoutViewImplementation.sizeThatFits(self, size: size) ?? super.sizeThatFits(size) + } + + public override func quick_flexibility(for axis: QuickLayoutCore.Axis) -> Flexibility { + return _QuickLayoutViewImplementation.quick_flexibility(self, for: axis) ?? super.quick_flexibility(for: axis) + } + } + + extension TestView: HasBody { + } + """#, + diagnostics: [ + .init( + message: """ + Method 'willMove' is missing required implementation call. Below Swift 6.0, you must manually add the following call: + _QuickLayoutViewImplementation.willMove(self, toWindow: newWindow) + """, + line: 7, + column: 3 + ), + .init( + message: """ + Method 'layoutSubviews' is missing required implementation call. Below Swift 6.0, you must manually add the following call: + _QuickLayoutViewImplementation.layoutSubviews(self) + """, + line: 12, + column: 3 + ), + ], + macros: testMacros, + indentationWidth: .spaces(2) + ) +#endif } func testTypeScopedFunctionsDoNotConflict() throws { @@ -476,3 +550,4 @@ class QuickLayoutTests: XCTestCase { ) } } +#endif