Skip to content

Add imports_at_top rule - #6951

Open
udithaAnuranjana wants to merge 1 commit into
realm:mainfrom
udithaAnuranjana:add-imports-at-top-rule
Open

udithaAnuranjana wants to merge 1 commit into
realm:mainfrom
udithaAnuranjana:add-imports-at-top-rule

Conversation

@udithaAnuranjana

Copy link
Copy Markdown

Summary

Adds a new opt-in imports_at_top style rule that requires file-scope imports to appear before other declarations.

This addresses #6892, where sorted_imports can sort import groups but does not report imports placed after other code.

Behavior

The rule:

  • Allows regular and @testable imports at the beginning of a file.
  • Allows leading conditional import groups using #if, #elseif, and #else.
  • Supports nested conditional import groups.
  • Reports imports that appear after another declaration.

Example violation:

import Foundation

struct Foo {}

import UIKit // violation

Leading conditional imports remain valid:

#if canImport(UIKit)
import UIKit
#endif

import Foundation

struct Foo {}

Implementation

  • Adds ImportsAtTopRule as an opt-in SwiftSyntax style rule.
  • Reports violations at the import keyword.
  • Keeps the rule lint-only; autocorrection is not included.
  • Updates existing SwiftLint plugin imports to comply with the new rule.
  • Registers the rule and generated tests using make register.

Testing

  • swift test --filter ImportsAtTopRuleGeneratedTests
  • swift test

Full test suite: 1113 tests in 378 suites passed.

Closes #6892.

@SwiftLintBot

Copy link
Copy Markdown
88 Warnings
⚠️ This PR introduced a violation in Aerial: /Aerial/Source/Models/Extensions/AVAsset+VideoOrientation.swift:60:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Alamofire: /Source/Features/MultipartFormData.swift:547:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Alamofire: /Tests/ConcurrencyTests.swift:794:18: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /iOS/DuckDuckGo/Subscription/Onboarding/Views/SubscriptionOnboardingCard.swift:145:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /iOS/DuckDuckGo/Fire/GranularFireConfirmationView.swift:196:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /iOS/DuckDuckGo/Fire/GranularFireConfirmationView.swift:197:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /iOS/DuckDuckGo/Fire/GranularFireConfirmationView.swift:198:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /iOS/DuckDuckGo/DaxEasterEggLogos/DaxEasterEggZoomTransitionAnimator.swift:29:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /SharedPackages/SERPSettings/Tests/SERPSettingsTests/Mocks/MockSERPSettingsProvider.swift:121:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /SharedPackages/Onboarding/Sources/Onboarding/SwiftUIExtensions/AnimatableTypingText.swift:25:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /SharedPackages/Onboarding/Sources/Onboarding/SwiftUIExtensions/AnimatableTypingText.swift:26:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /SharedPackages/Onboarding/Sources/Onboarding/SwiftUIExtensions/AnimatableTypingText.swift:27:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /macOS/LocalPackages/NetworkQualityMonitor/Sources/NetworkQualityMonitor/NetworkQualityView.swift:494:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /macOS/DuckDuckGo/Preferences/View/PreferencesWebsitePermission/PreferencesWebsitePermissionsView.swift:162:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /macOS/DuckDuckGo/Fire/View/FirePopoverViewController.swift:265:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /macOS/DuckDuckGo/Fire/View/FirePopoverViewController.swift:266:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /macOS/DuckDuckGo/DBP/DBPHomeViewController.swift:263:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /macOS/DuckDuckGo/DBP/DBPHomeViewController.swift:264:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /macOS/DuckDuckGo/DBP/DBPHomeViewController.swift:265:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /macOS/DuckDuckGo/TabPreview/TabPreviewViewController.swift:233:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /macOS/DuckDuckGo/YoutubePlayer/Onboarding/DuckPlayerOnboardingModal/DuckPlayerOnboardingDecider.swift:57:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /SharedPackages/BrowserServicesKit/Tests/DuckPlayerTests/DuckPlayerContingencyHandlerTests.swift:231:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in DuckDuckGo: /SharedPackages/BrowserServicesKit/Tests/DDGSyncTests/SyncConnectionControllerTests.swift:157:16: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Moya: /Package.swift:83:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in NetNewsWire: /Shared/Extensions/NSAttributedString+Extensions.swift:16:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in NetNewsWire: /Modules/RSCore/Sources/RSCore/RSScreen.swift:22:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in NetNewsWire: /Modules/RSCore/Sources/RSCore/RSImage.swift:20:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Utils/NimbleTimeInterval.swift:85:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/BeAKindOf.swift:31:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/SatisfyAnyOf.swift:96:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/HaveCount.swift:46:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/Match.swift:13:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/Matcher.swift:208:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/Equal.swift:263:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/BeLessThanOrEqual.swift:20:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/SatisfyAllOf.swift:96:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/BeLessThan.swift:20:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/AllPass.swift:67:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/AllPass.swift:68:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/AllPass.swift:69:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/BeGreaterThan.swift:20:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/BeGreaterThanOrEqualTo.swift:21:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/ContainElementSatisfying.swift:48:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/ContainElementSatisfying.swift:49:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/ContainElementSatisfying.swift:50:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/BeNil.swift:47:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/Matchers/BeIdenticalTo.swift:61:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/ExpectationMessage.swift:205:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/DSL.swift:117:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Nimble: /Sources/Nimble/DSL.swift:118:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in PocketCasts: /podcasts/ExpandedCollectionViewController.swift:249:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in PocketCasts: /podcasts/SinglePodcastViewController.swift:206:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in PocketCasts: /podcasts/HorizontalCollectionListViewController.swift:42:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in PocketCasts: /podcasts/SmallPagedListSummaryViewController.swift:305:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in PocketCasts: /podcasts/DiscoverNetworksListViewController.swift:42:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in PocketCasts: /podcasts/LargeListSummaryViewController.swift:273:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in PocketCasts: /podcasts/SingleEpisodeViewController.swift:154:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in PocketCasts: /podcasts/FeaturedSummaryViewController.swift:300:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in PocketCasts: /podcasts/CategoryPodcastsViewController.swift:201:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in PocketCasts: /podcasts/Categories/CategoriesSelectorViewController.swift:149:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in PocketCasts: /podcasts/CategorySummaryViewController.swift:100:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Quick: /Tests/QuickLintTests/Result+CapturingAsync.swift:15:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Quick: /Tests/QuickLintTests/Result+CapturingAsync.swift:16:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Quick: /Plugins/LintError/LintError.swift:43:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Quick: /Plugins/DefocusCommandPlugin/DefocusCommandPlugin.swift:45:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Quick: /Plugins/LintCommandPlugin/LintCommandPlugin.swift:45:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Quick: /Plugins/LintWarning/LintWarning.swift:43:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Sourcery: /SourceryExecutable/main.swift:252:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Sourcery: /Plugins/SourceryCommandPlugin/SourceryCommandPlugin.swift:50:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Swift: /stdlib/public/core/StringStorage.swift:189:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Swift: /stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:32:10: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Swift: /stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:33:10: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Swift: /stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:34:10: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Swift: /stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:35:10: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Swift: /stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:36:10: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Swift: /stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:37:10: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Swift: /stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:133:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Swift: /stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:135:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Swift: /stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:137:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Swift: /stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift:139:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Swift: /stdlib/private/StdlibUnicodeUnittest/StdlibUnicodeUnittest.swift:76:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Wire: /WireMessaging/Sources/WireMessagingUI/Conversation/ConversationMessagesViewController.swift:161:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Wire: /wire-ios-data-model/Source/Utilis/ZMUpdateEvent.swift:27:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in Wire: /wire-ios-data-model/Support/Sourcery/generated/AutoMockable.manual.swift:321:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in WordPress: /WordPress/Classes/Utility/Analytics/ScreenTracking.swift:67:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in WordPress: /WordPress/Classes/Utility/Analytics/ScreenTracking.swift:83:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in WordPress: /Modules/Sources/WordPressUI/Views/AdaptiveTabBar.swift:361:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
⚠️ This PR introduced a violation in WordPress: /Modules/Sources/WordPressKit/DeviceInformationProvider.swift:25:1: Warning: Imports should appear at the beginning of the file (imports_at_top)
20 Messages
📖 Building this branch resulted in a binary size of 28796.74 KiB vs 28755.54 KiB when built on main (0% larger).
📖 Linting Aerial with this PR took 0.68 s vs 0.68 s on main (0% slower).
📖 Linting Alamofire with this PR took 0.97 s vs 0.97 s on main (0% slower).
📖 Linting Brave with this PR took 5.55 s vs 5.52 s on main (0% slower).
📖 Linting Brigade with this PR took 18.2 s vs 18.2 s on main (0% slower).
📖 Linting DuckDuckGo with this PR took 33.19 s vs 32.96 s on main (0% slower).
📖 Linting Firefox with this PR took 11.81 s vs 11.81 s on main (0% slower).
📖 Linting Kickstarter with this PR took 7.4 s vs 7.36 s on main (0% slower).
📖 Linting Moya with this PR took 0.38 s vs 0.38 s on main (0% slower).
📖 Linting NetNewsWire with this PR took 2.59 s vs 2.59 s on main (0% slower).
📖 Linting Nimble with this PR took 0.56 s vs 0.56 s on main (0% slower).
📖 Linting PocketCasts with this PR took 7.46 s vs 7.41 s on main (0% slower).
📖 Linting Quick with this PR took 0.36 s vs 0.36 s on main (0% slower).
📖 Linting Realm with this PR took 3.0 s vs 2.97 s on main (1% slower).
📖 Linting Sourcery with this PR took 1.61 s vs 1.64 s on main (1% faster).
📖 Linting Swift with this PR took 4.63 s vs 4.61 s on main (0% slower).
📖 Linting SwiftLintPerformanceTests with this PR took 0.18 s vs 0.18 s on main (0% slower).
📖 Linting VLC with this PR took 1.44 s vs 1.43 s on main (0% slower).
📖 Linting Wire with this PR took 16.56 s vs 16.57 s on main (0% faster).
📖 Linting WordPress with this PR took 10.65 s vs 10.67 s on main (0% faster).

Generated by 🚫 Danger

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rule Request: imports_at_top

2 participants