Advantages of having typical errors at a common place:
* Error message styling can be harmonized
* Existing messages can be reused
* Overview of prefixes ('error: ', 'warning: ')
* Manage how to print them to the console
The CLI target shouldn't be importing SwiftLintFramework with
`@_spi(TestHelper)`. If the CLI target needs to access something in
SwiftLintFramework, that declaration should be `public`.
With the memory increase related to
https://github.com/apple/swift-syntax/issues/921,
I wanted a way to quickly know how much memory was being used by
SwiftLint.
Here's how much memory it took to lint SwiftLint itself at various
versions in the last few weeks:
* 0.49.1: 223 MB
* 0.50.0-rc.1: 356 MB
* 0.50.0-rc.2: 444 MB
* main (458916174): 464 MB
```console
$ swiftlint --progress --benchmark
Linting Swift files in current working directory
529 of 529 [==============================] ETA: 0s (121 files/s)
Done linting! Found 0 violations, 0 serious in 529 files.
Memory used: 464 MB
$ swiftlint --progress --benchmark
Linting Swift files in current working directory
529 of 529 [==============================] ETA: 0s (16220 files/s)
Done linting! Found 0 violations, 0 serious in 529 files.
Memory used: 55.8 MB
```
To support this, we first must use an async entrypoint to the CLI, which
we do by changing the lint and analyze commands to conform to
`AsyncParsableCommand`.
The in order to map over the closures with suspension points, we pull in
CollectionConcurrencyKit as a new dependency.
This change does not touch SwiftLintFramework, only the CLI target.
A colleague was confused by the output of `swiftlint autocorrect`, she
couldn't understand why SwiftLint told her it corrected thousands of
files when she only touched one.
The "Done correcting \(files.count) ..." output made her think that a
change was made on each of the `files`, when really they had only been
inspected.
A good solution would be to adopt a similar approach as the `lint`
command does.
Not being familiar with the codebase, I though a good first step could
have been to tweak the message a bit, making it clearer that the count
printed to the console is the inspected files.
* Integrate OS Signposts to help profile SwiftLint performance
* Split LintOrAnalyzeCommand.lintOrAnalyze(_:) into two functions
Using a builder reference type to share common mutable state.
A colleague was confused by the output of `swiftlint autocorrect`, she
couldn't understand why SwiftLint told her it corrected thousands of
files when she only touched one.
The "Done correcting \(files.count) ..." output made her think that a
change was made on each of the `files`, when really they had only been
inspected.
A good solution would be to adopt a similar approach as the `lint`
command does.
Not being familiar with the codebase, I though a good first step could
have been to tweak the message a bit, making it clearer that the count
printed to the console is the inspected files.
As we discussed here https://github.com/realm/SwiftLint/pull/3325 sometimes current excluding algorithm maybe slower than excluding paths by absolute prefix. So I added option for such cases.
Based on what I've checked it works faster for next scenarios:
- the number of input files is relatively small (e.g. when using `use-script-input-files`) and excluded directories contain relatively big number of lintable files
- the number of excluded directories relatively small (e.g. Pods + ThirdParty) and globs not used
* Add Example wrapper in order to display test failures inline when running in Xcode.
* Stop using Swift 5.1-only features so we can compile on Xcode 10.2.
* Wrap strings in Example.
* Add Changelog entry.
* Wrap all examples in Example struct.
* Better and more complete capturing of line numbers.
* Fix broken test.
* Better test traceability.
* Address or disable linting warnings.
* Add documentation comments.
* Disable linter for a few cases.
* Limit mutability and add copy-and-mutate utility functions.
* Limit scope of mutability.
* Add --compile-commands flag
* Implement support for --compile-commands
* Turns out you can't use yaml to read compile_commands.json
* refactor all the things
* Add changelog entry
* formatting
* Add comment and typealiases
* typo
* fix bool logic
* support directory field in compile commands
* remove "directory" field support
* filter compilation database args too
* Remove initial `swiftc` from args
* grammar
In order for rules to collect arbitrary information about all files
being linted, a shared RuleStorage instance is defined in each command
and passed into the linter.
Linting now requires two "passes": once to call collect and populate the
storage (rules that are non-collecting do nothing here), and again to
call validate. The old Linter factory now creates a Prelinter, which can
collect for a file and produce a Linter that orchestrates all the
traditional validation/collection logic.
This design enforces that a file is only validated once it has been
collected; in turn, the file-visiting loop ensures that all files are
collected before the first is validated, so that the storage is fully
populated.
Use storage-backed correct method
Crash if storage for a rule is accessed prematurely
Key FileInfo by File
Rename Prelinter to Linter and Linter to CollectedLinter
Clean up rule protocols such that rule-facing storage methods are actually called
Make RuleStorage a reference type to solve mutating data races
* Add LintableFilesVisitor
* Move LintCommand logic into LintOrAnalyzeCommand
to prepare for the upcoming analyze command
* Add AnalyzeCommand (not fully implemented yet in SwiftLintFramework)
* Add analyzerRules configuration member
* Add AnalyzerRule protocol
* Pass compiler arguments to validate/correct
* Add requiresFileOnDisk member to RuleDescription
This will be used by AnalyzerRules because they need a file on disk
to pass in the compiler arguments to SourceKit.
* Exclusively run AnalyzerRules when the Linter has compiler arguments
* Enable testing AnalyzerRules in TestHelpers
* Add ExplicitSelfRule
* Update documentation
* Fix `analyze --autocorrect`
* Improve performance of CompilerArgumentsExtractor
* Fix lint command actually running analyze
* Move File operations in TestHelpers into a private extension
* Add analyzer column to rules command and markdown documentation
* Use a Set literal
* Make AnalyzerRule inherit from OptInRule
* Mention analyzer_rules in readme
* Mention that analyzer rules are slow