Files
SwiftLint/Source/SwiftLintFramework/Rules/Style/ModifierOrderRuleExamples.swift
T
JP Simard fa6bf50a22 Rethink body line count calculation (#4369)
A long-standing limitation with SourceKit's "editor open" request is
that we weren't able to get certain tokens, such as braces, brackets and
parentheses.

This meant that this code block would be counted as two lines:

```swift
print(
  "hi"
)
```

because the trailing `)` would be treated as a whitespace line.

This meant that our "body length" family of rules that measure the
effective line count of declarations like functions, types or closures
would often significantly under-count the number of content lines in a
body.

Now with SwiftSyntax, we can get all tokens, including the ones
SourceKit was previously ignoring, so we can get much more accurate line
counts when ignoring whitespace and comments.

In addition, we weren't very thorough in how we measured body length.

As an exercise, how many lines long would you say the body of this
function is?

```swift
func hello() {
  print("hello")
}
```

Does the body span one line or three lines?

I propose that we consistently ignore the left and right brace lines
when calculating the body line count of these scopes so that we measure
body line counts like this:

```swift
// 1 line
{ print("foo") }
// 1 line
{
}
// 1 line
{
  print("foo")
}
// 2 lines
{
  let sum = 1 + 2
  print(sum)
}
```

Now with those changes in place, in order to keep the default
configuration thresholds to similar levels as before, we need to adjust
them slightly. Here's what I'm suggesting:

|Rule|Before|After|
|-|-|-|
|closure_body_length|20/100|30/100|
|function_body_length|40/100|50/100|
|type_body_length|200/350|250/350|

This is a pretty significant breaking change and I suspect we'll hear
from users who are surprised that some of their declarations now exceed
the rule limits, but I believe this new approach to calculating body
lines is more correct and intuitive compared to what we've had until
now.

OSSCheck is also going to report a bazillion changes with this, which is
expected given the scope of this change.
2022-10-14 03:16:26 -04:00

229 lines
5.1 KiB
Swift

internal struct ModifierOrderRuleExamples {
static let nonTriggeringExamples = [
Example("""
public class Foo {
public required convenience init() {}
}
"""),
Example("""
public class Foo {
public static let bar = 42
}
"""),
Example("""
public class Foo {
public static var bar: Int {
return
}
}
"""),
Example("""
public class Foo {
public class var bar: Int {
return 42
}
}
"""),
Example("""
public class Bar {
public class var foo: String {
return "foo"
}
}
public class Foo: Bar {
override public final class var foo: String {
return "bar"
}
}
"""),
Example("""
open class Bar {
public var foo: Int? {
return 42
}
}
open class Foo: Bar {
override public var foo: Int? {
return 43
}
}
"""),
Example("""
open class Bar {
open class func foo() -> Int {
return 42
}
}
class Foo: Bar {
override open class func foo() -> Int {
return 43
}
}
"""),
Example("""
protocol Foo: class {}
class Bar {
public private(set) weak var foo: Foo?
}
"""),
Example("""
@objc
public final class Foo: NSObject {}
"""),
Example("""
@objcMembers
public final class Foo: NSObject {}
"""),
Example("""
@objc
override public private(set) weak var foo: Bar?
"""),
Example("""
@objc
public final class Foo: NSObject {}
"""),
Example("""
@objc
open final class Foo: NSObject {
open weak var weakBar: NSString? = nil
}
"""),
Example("""
public final class Foo {}
"""),
Example("""
class Bar {
func bar() {}
}
"""),
Example("""
internal class Foo: Bar {
override internal func bar() {}
}
"""),
Example("""
public struct Foo {
internal weak var weakBar: NSObject? = nil
}
"""),
Example("""
class Foo {
internal lazy var bar: String = "foo"
}
""")
]
static let triggeringExamples = [
Example("""
class Foo {
convenience required public init() {}
}
"""),
Example("""
public class Foo {
static public let bar = 42
}
"""),
Example("""
public class Foo {
static public var bar: Int {
return 42
}
}
"""),
Example("""
public class Foo {
class public var bar: Int {
return 42
}
}
"""),
Example("""
public class RootFoo {
class public var foo: String {
return "foo"
}
}
public class Foo: RootFoo {
override final class public var foo: String
return "bar"
}
}
"""),
Example("""
open class Bar {
public var foo: Int? {
return 42
}
}
open class Foo: Bar {
public override var foo: Int? {
return 43
}
}
"""),
Example("""
protocol Foo: class {}
class Bar {
private(set) public weak var foo: Foo?
}
"""),
Example("""
open class Bar {
open class func foo() -> Int {
return 42
}
}
class Foo: Bar {
class open override func foo() -> Int {
return 43
}
}
"""),
Example("""
open class Bar {
open class func foo() -> Int {
return 42
}
}
class Foo: Bar {
open override class func foo() -> Int {
return 43
}
}
"""),
Example("""
@objc
final public class Foo: NSObject {}
"""),
Example("""
@objcMembers
final public class Foo: NSObject {}
"""),
Example("""
@objc
final open class Foo: NSObject {
weak open var weakBar: NSString? = nil
}
"""),
Example("""
final public class Foo {}
"""),
Example("""
internal class Foo: Bar {
internal override func bar() {}
}
"""),
Example("""
public struct Foo {
weak internal var weakBar: NSObjetc? = nil
}
"""),
Example("""
class Foo {
lazy internal var bar: String = "foo"
}
""")
]
}