49 Commits

Author SHA1 Message Date
Danny Mösch ac701c088c Improve performance of excluded files filter (#6342)
The current algorithm is like "collect all included files and subtract all excluded files".
Collecting all included and all excluded files relies on the file system. This can become slow
when the patterns used to exclude files resolve to a large number of files.

The new approach only collects all lintable files and checks them against the exclude patterns.
This can be done by in-memory string-regex-match and does therefore not require file system accesses.
The new implementation also no longer traverses directories that already match an exclude pattern.

(cherry picked from commit 152355e36f)
2025-12-07 15:58:23 +01:00
Saleem Abdulrasool 339d250464 Port to Windows (#5030)
At least ensure it compiles just fine on Windows.

* build: add CryptoSwift dependency for Windows
* SwiftLintBuiltInRules: treat Windows similar to Linux wrt `NSDataDetector`
* SwiftLintCore: initial pass for Windows support

Add some Windows specific handling for the paths in SwiftLintCore.  The
one piece that this change does not cover is the handling of `glob` as
that is not an ISO C standard function and as such there is no `glob` on
Windows.  This will be worked through separately.

* swiftlint: add a Windows port

This enables building the swiftlint command on Windows.  There is no
system ioctl for terminal access, instead, we can use the Win32 Console
API surface to query the console size.  In the case of a failure, assume
the width to be 80-columns (as the standard VGA console is 80x25).

* WIP/SwiftLintCore: port the `glob` function to Windows

Windows does not support `glob` as a standard C library function as that
is not part of the C standard.  Attempt to emulate that through the use
of `FindFirstFileW` and `FindNextFile` to iterate the matching files
given a pattern.  This should allow us to start enumerating the files as
if we had `glob` available.
2025-11-21 09:59:28 +01:00
Danny Mösch 4065fc8437 Enable upcoming feature MemberImportVisibility (#6286) 2025-10-08 08:12:05 +02:00
Danny Mösch bae9a2a351 Remove deprecated connectivity check (#6278) 2025-10-04 11:35:34 +02:00
Danny Mösch fcdc98a52d Revert "Improve performance of excluded files filter" (#5962)
This reverts commit 152355e36f from #5157.

# Conflicts:
#	tools/oss-check
2025-01-15 19:15:44 +01:00
Danny Mösch 152355e36f Improve performance of excluded files filter (#5157)
The current algorithm is like "collect all included files and subtract all excluded files".
Collecting all included and all excluded files relies on the file system. This can become slow
when the patterns used to exclude files resolve to a large number of files.

The new approach only collects all lintable files and checks them against the exclude patterns.
This can be done by in-memory string-regex-match and does therefore not require file system accesses.
2024-12-25 17:33:33 -05:00
Danny Mösch a6c4fd98bc Move files from SwiftLintCore to SwiftLintFramework
Ideally, SwiftLintCore would some day only contain components
that are needed to define rules. Consequently, it would be the
only bundle required to import for (external) rule development.
2024-12-23 12:51:43 +01:00
JP Simard a7bc9e20c7 Move built-in rules to new SwiftLintBuiltInRules module (#4950) 2023-04-27 11:16:01 -04:00
JP Simard 86d60400c1 Move core SwiftLint functionality to new SwiftLintCore module
Over the years, SwiftLintFramework had become a fairly massive monolith,
containing over 400 source files with both core infrastructure and
rules.

Architecturally, the rules should rely on the core infrastructure but
not the other way around. There are two exceptions to this:
`custom_rules` and `superfluous_disable_command` which need special
integration with the linter infrastructure.

Now the time has come to formalize this architecture and one way to do
that is to move the core SwiftLint functionality out of
SwiftLintFramework and into a new SwiftLintCore module that the rules
can depend on.

Beyond enforcing architectural patterns, this also has the advantage of
speeding up incremental compilation by skipping rebuilding the core
functionality when iterating on rules.

Because the core functionality is always useful when building rules, I'm
opting to import SwiftLintCore in SwiftLintFramework as `@_exported` so
that it's implicitly available to all files in SwiftLintFramework
without needing to import it directly.

In a follow-up I'll also split the built-in rules and the extra rules
into their own modules. More modularization is possible from there, but
not planned.

The bulk of this PR just moves files from `Source/SwiftLintFramework/*`
to `Source/SwiftLintCore/*`. There are some other changes that can't be
split up into their own PRs:

* Change jazzy to document the SwiftLintCore module instead of
  SwiftLintFramework.
* Change imports in unit tests to reflect where code was moved to.
* Update `sourcery` make rule to reflect where code was moved to.
* Create a new `coreRules` array and register those rules with the
  registry. This allows the `custom_rules` and
  `superfluous_disable_command` rule implementations to remain internal
  to the SwiftLintCore module, preventing more implementation details
  from leaking across architectural layers.
* Move `RuleRegistry.registerAllRulesOnce()` out of the type declaration
  and up one level so it can access rules defined downstream from
  SwiftLintCore.
2023-04-26 21:10:19 -04:00
JP Simard 3a2bb15ca3 Make some SwiftLintFramework declarations public (#4945)
* Make some SwiftLintFramework declarations public

If built-in rules depend on them.

This will allow separating the rules from the core infrastructure in
separate modules in an upcoming PR.

It also helps formalize the API contract for what should be accessible
to rule implementations.

* Exclude extensions from jazzy
2023-04-26 16:37:25 -04:00
JP Simard 8a21549ca9 Change Reachability to an enum (#4941)
Since it's already acting as a namespace, might as well make it so it
can't be instantiated and can't have instance properties.
2023-04-26 13:55:17 -04:00
JP Simard 2544dc79d3 Move CustomRuleTimer to its own file (#4938)
And add docs.
2023-04-26 15:56:04 +00:00
Danny Mösch c241935635 Introduce basic Stack type (#4922) 2023-04-23 09:12:35 +00:00
JP Simard 70a56a1420 Update SwiftSyntax to 04-10 snapshot (#4887)
https://github.com/apple/swift-syntax/releases/tag/509.0.0-swift-5.9-DEVELOPMENT-SNAPSHOT-2023-04-10-a
2023-04-13 14:04:43 -04:00
JP Simard 2f0e537f9b Update SwiftSyntax to latest development snapshot (#4759)
* Merge `spacedBinaryOperator` and `unspacedBinaryOperator`

* New contextual keyword enums

* Update for removed `UnavailabilityConditionSyntax`

* Handle how attributes are now defined

This partially reverts commit 325d0ee1e4.

* Handle removal of `TokenListSyntax`

* Update `Package.swift`

* Extract some SwiftSyntax helpers

* Update to `0.50900.0-swift-DEVELOPMENT-SNAPSHOT-2023-02-06-a`

* Skip attributes with keypath arguments in `attributes` rule

To preserve the rule's existing behavior.

* Limit unowned_variable_capture violations to capture lists

* Add changelog entries
2023-02-20 10:51:31 -05:00
JP Simard 95d56e4130 Use raw in SwiftSyntaxBuilder string interpolation (#4623)
Fixing build warnings to account for
https://github.com/apple/swift-syntax/pull/1090.
2022-12-05 11:26:04 -05:00
JP Simard 4f652a68e7 Move XCTestHelpers to TestCaseAccessibilityRule.swift (#4552)
it's only used in that file
2022-11-16 14:31:00 -05:00
JP Simard 953ee620f7 Refactor ExecutableInfo (#4551)
To improve how it renders in jazzy-generated docs.
2022-11-16 14:07:39 -05:00
Marcelo Fabri 87bebb6744 Rewrite test_case_accessibility with SwiftSyntax (#4446) 2022-10-23 17:39:45 -07:00
Danny Mösch f8e5339c69 Introduce ReasonedRuleViolation type to associate a reason with a violation position (#4379) 2022-10-16 12:53:38 +02:00
Danny Mösch bd8c9e5bcb Provide syntax visitor base class allowing for convenient skipping of declaration nodes (#4310) 2022-10-15 19:03:49 +02:00
JP Simard 39bb05f7d1 Rewrite "body length" rules with SwiftSyntax (#4370)
- `closure_body_length`
- `function_body_length`
- `type_body_length`
2022-10-14 03:50:39 -04:00
JP Simard 9aaeff67d0 Add SyntaxProtocol.isContainedIn(regions:locationConverter:) helper (#4356) 2022-10-12 19:50:32 +00:00
Marcelo Fabri 04bd091810 Migrate legacy_multiple rule to SwiftSyntax (#4317) 2022-10-07 23:49:14 -07:00
JP Simard 549c71a27c Introduce LegacyFunctionRuleHelper (#4312) 2022-10-06 16:48:51 -04:00
JP Simard a6c90dd942 Rewrite legacy_cggeometry_functions with SwiftSyntax (#4309) 2022-10-06 15:16:49 -04:00
JP Simard 2388e49190 Use SwiftSyntax's new SwiftParser (#4216) 2022-10-01 15:05:36 -04:00
JP Simard 73c88c3af0 Add version --verbose command (#4102)
Prints out something like this on macOS:

```
Version: 0.49.0-rc.1
Build ID: B43931F3-D096-3704-B41C-FC40673A3F96
```

This can be used to determine if two `swiftlint` executables are
identical.
2022-08-16 14:12:44 +00:00
JP Simard c0f9f2175b Add support for native custom rules (#4039)
This change makes it possible to add native custom rules when building
SwiftLint via Bazel (possible as of
https://github.com/realm/SwiftLint/pull/4038).

First, add a local bazel repository where custom rules will be defined
to your project's `WORKSPACE`:

```python
local_repository(
    name = "swiftlint_extra_rules",
    path = "swiftlint_extra_rules",
)
```

Then in the extra rules directory, add an empty `WORKSPACE` and a
`BUILD` file with the following contents:

```python
filegroup(
    name = "extra_rules",
    srcs = glob(["*.swift"]),
    visibility = ["//visibility:public"],
)
```

To add a rule (for example, `MyPrivateRule`) add the following two
files:

```swift
// ExtraRules.swift
func extraRules() -> [Rule.Type] {
    [
        MyPrivateRule.self,
    ]
}
```

```swift
// MyPrivateRule.swift
import SourceKittenFramework
import SwiftSyntax

struct MyPrivateRule: ConfigurationProviderRule {
    var configuration = SeverityConfiguration(.error)

    init() {}

    static let description = RuleDescription(
        identifier: "my_private_rule",
        name: "My Private Rule",
        description: "This is my private rule.",
        kind: .idiomatic
    )

    func validate(file: SwiftLintFile) -> [StyleViolation] {
        // Perform validation here...
    }
}
```

Then you can reference the rule in your configuration or source files as
though they were built in to the official SwiftLint repo.

This means that you have access to SwiftLintFramework's internal API.
We make no guarantees as to the stability of these internal APIs,
although if you end up using something that gets removed please reach
out and we'll make a best effort to maintain some level of support.

This PR also improves the linter cache on macOS to make it correctly
invalidate previous results when custom native rules are edited. This
even works when doing local development of SwiftLint, where previous it
was necessary to use `--no-cache` when working on SwiftLint, now the
cache should always work.

Co-authored-by: Keith Smiley <keithbsmiley@gmail.com>
2022-07-26 13:56:22 -04:00
JP Simard 1abc50304c Use alternate implementation of glob with globstar support (#3892)
Adapted from https://gist.github.com/efirestone/ce01ae109e08772647eb061b3bb387c3

The implementation from Pathos seems buggy.

Fixes https://github.com/realm/SwiftLint/issues/3891
2022-03-11 13:24:39 -05:00
Fumito Nakazawa 2ae22d06a2 Support recursive globs (#3843)
ref: https://github.com/realm/SwiftLint/issues/3789

## Overview
Support glob recursive by using [Pathos](https://github.com/dduan/Pathos)
- Introduce Pathos
- Replace glob logic
- Fix some test cases
2022-03-10 21:56:43 -05:00
JP Simard 28dd673c48 Use SwiftSyntax visitor to parse commands (#3872)
* Cache SwiftSyntax syntax trees
* Use SwiftSyntax visitor to parse commands
* Update changelog entry
* Cache commands
2022-03-08 12:33:06 -05:00
Keith Smiley 7976b74615 Add test functions with parameters to TestCaseAccessibilityRule (#3612)
If a function starts with `test` but takes some parameters, it is not
actually a test.
2021-04-26 20:04:04 +00:00
Frederick Pietschmann 4c5a3f0577 Add remote, parent & child configuration features 2020-11-20 23:08:37 +01:00
Keith Smiley 5d6e25ae5f Add TestCaseAccessibilityRule (#3376)
Co-authored-by: JP Simard <jp@jpsim.com>
2020-10-12 08:59:45 -07:00
JP Simard fe5baca7cd Migrate to use SourceKitten's new ByteCount/ByteRange types (#3037)
New APIs were introduced in SourceKitten to allow for a more typesafe distinction between integers meaning NSString-based distances and byte-based distances.

* https://github.com/jpsim/SourceKitten/pull/639
* https://github.com/jpsim/SourceKitten/pull/642

This PR migrates SwiftLint's use of those APIs.
2020-01-16 15:18:37 -08:00
JP Simard 37167a8a35 Add documentation comments to all public declarations (#3027) 2020-01-08 09:47:10 -08:00
Paul Taykalo b1cdc119ec Use swift enums instead of raw values 2019-11-07 11:05:19 +02:00
Paul Taykalo 8c963d2c15 Working solution with SouceKittenDictionary wrapper 2019-11-07 08:50:50 +02:00
Maksym Grebenets 46aed849d6 Support glob patterns without the star (#2508)
Enables use of '[abc]', '?' and '[a-z]' glob syntax without the need to use '*' in the pattern.
2018-12-23 16:02:42 -08:00
JP Simard 0e862ca9c4 Enable vertical whitespace rules in SwiftLint
and fix violations
2018-12-02 14:01:23 -08:00
JP Simard 5901d3075f Require Swift 4.2 (#2466)
This bumps the minimum version required to build SwiftLint to 4.2. The primary motivating factor to drop support for Swift 4.0-4.1.x is that SwiftLint now uses CryptoSwift, which requires 4.2.

* Add changelog entry

* Remove --allow-warnings flag from CocoaPods commands

* Update CryptoSwift to 0.13.0

* Migrate to Swift 4.2

* Remove CircleCI tests for Swift < 4.2

* Update English and Chinese README

Korean README doesn't yet have a version table like this.

* Update gems

* Add changelog entry for fixed compiler warnings

* Update CocoaPods to 1.6.0.beta.2

To work around https://github.com/CocoaPods/CocoaPods/issues/7708
2018-11-18 17:32:25 -08:00
JP Simard dcc85fb0f3 Remove unused imports (#2382) 2018-09-02 14:09:04 -07:00
Keith Smiley 2515c0f936 flatMap it 2018-07-26 10:21:13 -07:00
Keith Smiley 97dc3b69e5 Rename function 2018-07-26 10:21:13 -07:00
Keith Smiley b21307530c Move glob to its own struct 2018-07-26 10:21:13 -07:00
JP Simard b83e0991b9 Remove all file headers
The MIT license doesn't require that all files be prepended with this
licensing or copyright information. Realm confirmed that they're ok with this
change. This will enable some companies to contribute to SwiftLint and the
date & authorship information will remain accessible via git source control.
2018-05-04 13:42:02 -07:00
Marcelo Fabri c384ec4f19 Don’t trigger violations for extensions in same file 2017-10-07 20:28:11 -03:00
Blaise Sarr 20ef756c40 Add RegexHelpers file
- This will be used to centralize common used regex and avoid duplicate them
2016-04-17 14:56:03 +02:00