Format code (#6151)

This commit is contained in:
Danny Mösch
2025-07-02 23:50:53 +02:00
committed by GitHub
parent 097bef27ef
commit 599e51a5a2
83 changed files with 279 additions and 284 deletions
@@ -238,11 +238,11 @@ private extension ExprSyntax {
return true
}
if let expr = self.as(MemberAccessExprSyntax.self),
expr.description.split(separator: ".").allSatisfy(\.startsWithUppercase) {
expr.description.split(separator: ".").allSatisfy(\.startsWithUppercase) {
return true
}
if let expr = self.as(GenericSpecializationExprSyntax.self)?.expression.as(DeclReferenceExprSyntax.self),
expr.baseName.text.startsWithUppercase {
expr.baseName.text.startsWithUppercase {
return true
}
return false
@@ -13,9 +13,9 @@ struct FileNameNoSpaceRule: OptInRule, SourceKitFreeRule {
func validate(file: SwiftLintFile) -> [StyleViolation] {
guard let filePath = file.path,
case let fileName = filePath.bridge().lastPathComponent,
!configuration.excluded.contains(fileName),
fileName.rangeOfCharacter(from: .whitespaces) != nil else {
case let fileName = filePath.bridge().lastPathComponent,
!configuration.excluded.contains(fileName),
fileName.rangeOfCharacter(from: .whitespaces) != nil else {
return []
}
@@ -24,13 +24,13 @@ struct FileNameRule: OptInRule, SourceKitFreeRule {
// Process prefix
if let match = prefixRegex.firstMatch(in: typeInFileName, options: [], range: typeInFileName.fullNSRange),
let range = typeInFileName.nsrangeToIndexRange(match.range) {
let range = typeInFileName.nsrangeToIndexRange(match.range) {
typeInFileName.removeSubrange(range)
}
// Process suffix
if let match = suffixRegex.firstMatch(in: typeInFileName, options: [], range: typeInFileName.fullNSRange),
let range = typeInFileName.nsrangeToIndexRange(match.range) {
let range = typeInFileName.nsrangeToIndexRange(match.range) {
typeInFileName.removeSubrange(range)
}
@@ -38,10 +38,10 @@ struct FileNameRule: OptInRule, SourceKitFreeRule {
let allDeclaredTypeNames = TypeNameCollectingVisitor(
requireFullyQualifiedNames: configuration.requireFullyQualifiedNames
)
.walk(tree: file.syntaxTree, handler: \.names)
.map {
$0.replacingOccurrences(of: ".", with: configuration.nestedTypeSeparator)
}
.walk(tree: file.syntaxTree, handler: \.names)
.map {
$0.replacingOccurrences(of: ".", with: configuration.nestedTypeSeparator)
}
guard allDeclaredTypeNames.isNotEmpty, !allDeclaredTypeNames.contains(typeInFileName) else {
return []
@@ -67,7 +67,7 @@ private extension GenericTypeNameRule {
)
)
} else if let caseCheckSeverity = configuration.validatesStartWithLowercase.severity,
!String(name[name.startIndex]).isUppercase() {
!String(name[name.startIndex]).isUppercase() {
violations.append(
ReasonedRuleViolation(
position: node.positionAfterSkippingLeadingTrivia,
@@ -62,8 +62,8 @@ private extension ObjectLiteralRule {
private func isColorInit(node: FunctionCallExprSyntax, name: String) -> Bool {
guard inits(forClasses: ["UIColor", "NSColor"]).contains(name),
case let argumentsNames = node.arguments.compactMap(\.label?.text),
argumentsNames == ["red", "green", "blue", "alpha"] || argumentsNames == ["white", "alpha"] else {
return false
argumentsNames == ["red", "green", "blue", "alpha"] || argumentsNames == ["white", "alpha"] else {
return false
}
return node.arguments.allSatisfy(\.expression.canBeExpressedAsColorLiteralParams)
@@ -63,7 +63,7 @@ private extension Syntax {
return true
}
if let variableDecl = self.as(VariableDeclSyntax.self),
variableDecl.bindings.allSatisfy({ $0.accessorBlock == nil }) {
variableDecl.bindings.allSatisfy({ $0.accessorBlock == nil }) {
return true
}
return false
@@ -93,12 +93,12 @@ private extension AttributeListSyntax {
return nil
}
if parent?.isFunctionOrStoredProperty == true,
let parentClassDecl = parent?.parent?.parent?.parent?.parent?.as(ClassDeclSyntax.self),
parentClassDecl.attributes.contains(attributeNamed: "objcMembers") {
let parentClassDecl = parent?.parent?.parent?.parent?.parent?.as(ClassDeclSyntax.self),
parentClassDecl.attributes.contains(attributeNamed: "objcMembers") {
return parent?.functionOrVariableModifiers?.containsPrivateOrFileprivate() == true ? nil : objcAttribute
}
if let parentExtensionDecl = parent?.parent?.parent?.parent?.parent?.as(ExtensionDeclSyntax.self),
parentExtensionDecl.attributes.objCAttribute != nil {
parentExtensionDecl.attributes.objCAttribute != nil {
return objcAttribute
}
return nil
@@ -111,7 +111,7 @@ extension RedundantObjcAttributeRule {
let nsCharSet = CharacterSet.whitespacesAndNewlines.bridge()
let nsContent = file.contents.bridge()
while nsCharSet
.characterIsMember(nsContent.character(at: violationRange.upperBound + whitespaceAndNewlineOffset)) {
.characterIsMember(nsContent.character(at: violationRange.upperBound + whitespaceAndNewlineOffset)) {
whitespaceAndNewlineOffset += 1
}
@@ -116,7 +116,7 @@ private extension ReturnClauseSyntax {
return false
}
if let simpleReturnType = type.as(IdentifierTypeSyntax.self) {
return simpleReturnType.typeName == "Void"
return simpleReturnType.typeName == "Void"
}
if let tupleReturnType = type.as(TupleTypeSyntax.self) {
return tupleReturnType.elements.isEmpty
@@ -90,7 +90,7 @@ private extension TypeNameRule {
)
}
if let caseCheckSeverity = nameConfiguration.validatesStartWithLowercase.severity,
name.first?.isLowercase == true {
name.first?.isLowercase == true {
return ReasonedRuleViolation(
position: identifier.positionAfterSkippingLeadingTrivia,
reason: "Type name '\(name)' should start with an uppercase character",
@@ -50,9 +50,9 @@ struct UnneededBreakInSwitchRule: Rule {
],
corrections: [
embedInSwitch("something()\n ↓break")
: embedInSwitch("something()"),
: embedInSwitch("something()"),
embedInSwitch("something()\n ↓break // line comment")
: embedInSwitch("something()\n // line comment"),
: embedInSwitch("something()\n // line comment"),
embedInSwitch("""
something()
↓break
@@ -60,14 +60,14 @@ struct UnneededBreakInSwitchRule: Rule {
block comment
*/
""")
: embedInSwitch("""
: embedInSwitch("""
something()
/*
block comment
*/
"""),
embedInSwitch("something()\n ↓break /// doc line comment")
: embedInSwitch("something()\n /// doc line comment"),
: embedInSwitch("something()\n /// doc line comment"),
embedInSwitch("""
something()
↓break
@@ -75,16 +75,16 @@ struct UnneededBreakInSwitchRule: Rule {
/// doc block comment
///
""")
: embedInSwitch("""
: embedInSwitch("""
something()
///
/// doc block comment
///
"""),
embedInSwitch("something()\n ↓break", case: "default")
: embedInSwitch("something()", case: "default"),
: embedInSwitch("something()", case: "default"),
embedInSwitch("something()\n ↓break", case: "case .foo, .foo2 where condition")
: embedInSwitch("something()", case: "case .foo, .foo2 where condition"),
: embedInSwitch("something()", case: "case .foo, .foo2 where condition"),
]
)
}
@@ -243,9 +243,9 @@ private extension FunctionCallExprSyntax {
var enumeratedPosition: AbsolutePosition? {
if let memberAccess = calledExpression.as(MemberAccessExprSyntax.self),
memberAccess.base != nil,
memberAccess.declName.baseName.text == "enumerated",
hasNoArguments {
memberAccess.base != nil,
memberAccess.declName.baseName.text == "enumerated",
hasNoArguments {
return memberAccess.declName.positionAfterSkippingLeadingTrivia
}
@@ -234,9 +234,9 @@ private extension CodeBlockItemSyntax {
}
private extension FunctionSignatureSyntax {
var allowsImplicitReturns: Bool {
returnClause?.allowsImplicitReturns ?? false
}
var allowsImplicitReturns: Bool {
returnClause?.allowsImplicitReturns ?? false
}
}
private extension SubscriptDeclSyntax {
@@ -25,7 +25,7 @@ private extension XCTSpecificMatcherRule {
reason: "Prefer the specific matcher '\(suggestion)' instead"
))
} else if configuration.matchers.contains(.oneArgumentAsserts),
let suggestion = OneArgXCTAssert.violations(in: node) {
let suggestion = OneArgXCTAssert.violations(in: node) {
violations.append(ReasonedRuleViolation(
position: node.positionAfterSkippingLeadingTrivia,
reason: "Prefer the specific matcher '\(suggestion)' instead"
@@ -139,7 +139,7 @@ private extension FunctionCallExprSyntax {
let modifierName = memberAccess.declName.baseName.text
if funcCall.isDirectAccessibilityModifier(modifierName) ||
funcCall.isContainerExemptingModifier(modifierName) {
funcCall.isContainerExemptingModifier(modifierName) {
return true
}
}
@@ -187,7 +187,7 @@ private extension FunctionCallExprSyntax {
let modifierName = memberAccess.declName.baseName.text
if funcCall.isDirectAccessibilityModifier(modifierName) ||
funcCall.isContainerExemptingModifier(modifierName) {
funcCall.isContainerExemptingModifier(modifierName) {
return true
}
@@ -374,7 +374,7 @@ internal struct AccessibilityLabelForImageRuleExamples {
}
}
"""),
// MARK: - SwiftSyntax Migration Detection Improvements
// MARK: - SwiftSyntax Migration Detection Improvements
// These violations would have been missed by the SourceKit implementation
// but are now correctly detected by SwiftSyntax
Example("""
@@ -161,8 +161,8 @@ private struct AccessibilityButtonTraitDeterminator {
// Stop if we reach a new View declaration or similar boundary
if currentSyntaxNode.is(StructDeclSyntax.self) ||
currentSyntaxNode.is(ClassDeclSyntax.self) ||
currentSyntaxNode.is(EnumDeclSyntax.self) {
currentSyntaxNode.is(ClassDeclSyntax.self) ||
currentSyntaxNode.is(EnumDeclSyntax.self) {
break
}
}
@@ -131,7 +131,7 @@ private extension ClosureSignatureSyntax {
return list.onlyElement?.name.text
}
if let clause = parameterClause?.as(ClosureParameterClauseSyntax.self), clause.parameters.count == 1,
clause.parameters.first?.secondName == nil {
clause.parameters.first?.secondName == nil {
return clause.parameters.first?.firstName.text
}
return nil
@@ -121,7 +121,7 @@ private extension AsyncWithoutAwaitRule {
override func visitPost(_ node: VariableDeclSyntax) {
if node.bindingSpecifier.tokenKind == .keyword(.let),
node.modifiers.contains(keyword: .async) {
node.modifiers.contains(keyword: .async) {
functionScopes.modifyLast {
$0.containsAwait = true
}
@@ -61,7 +61,7 @@ struct BlanketDisableCommandRule: Rule, SourceKitFreeRule {
"""),
Example("// swiftlint:disable all"),
].skipWrappingInCommentTests().skipDisableCommandTests()
)
)
func validate(file: SwiftLintFile) -> [StyleViolation] {
var violations: [StyleViolation] = []
@@ -42,7 +42,7 @@ private extension CompilerProtocolInitRule {
let argumentsNames = arguments.map(\.text)
for compilerProtocol in ExpressibleByCompiler.allProtocols {
guard compilerProtocol.initCallNames.contains(name),
compilerProtocol.match(arguments: argumentsNames) else {
compilerProtocol.match(arguments: argumentsNames) else {
continue
}
@@ -105,12 +105,12 @@ private extension DeploymentTargetRule {
violationType: AvailabilityType) -> String? {
guard let platform = DeploymentTargetConfiguration.Platform(rawValue: platform.text),
let minVersion = platformToConfiguredMinVersion[platform.rawValue] else {
return nil
return nil
}
guard let version = try? Version(platform: platform, value: versionString),
version <= minVersion else {
return nil
version <= minVersion else {
return nil
}
return """
@@ -220,9 +220,9 @@ private extension SyntaxProtocol {
return false
}
let ifConfigDecl = itemList
.parent?.as(IfConfigClauseSyntax.self)?
.parent?.as(IfConfigClauseListSyntax.self)?
.parent?.as(IfConfigDeclSyntax.self)
.parent?.as(IfConfigClauseSyntax.self)?
.parent?.as(IfConfigClauseListSyntax.self)?
.parent?.as(IfConfigDeclSyntax.self)
if let ifConfigDecl {
return ifConfigDecl.hasDocComment
}
@@ -303,19 +303,19 @@ private extension Stack<AccessControlBehavior> {
func computeAcl(givenExplicitAcl acl: AccessControlLevel?, evalEffectiveAcl: Bool) -> AccessControlLevel {
if let parentBehavior = peek() {
switch parentBehavior {
case .local:
.private
case .actor, .class, .struct, .enum:
if let acl {
acl < parentBehavior.effectiveAcl || !evalEffectiveAcl ? acl : parentBehavior.effectiveAcl
} else {
parentBehavior.effectiveAcl >= .internal ? .internal : parentBehavior.effectiveAcl
}
case .protocol:
parentBehavior.effectiveAcl
case .extension:
acl ?? parentBehavior.effectiveAcl
}
case .local:
.private
case .actor, .class, .struct, .enum:
if let acl {
acl < parentBehavior.effectiveAcl || !evalEffectiveAcl ? acl : parentBehavior.effectiveAcl
} else {
parentBehavior.effectiveAcl >= .internal ? .internal : parentBehavior.effectiveAcl
}
case .protocol:
parentBehavior.effectiveAcl
case .extension:
acl ?? parentBehavior.effectiveAcl
}
} else {
acl ?? .internal
}
@@ -99,7 +99,7 @@ private func isOrphanedDocComment(
while let (_, piece) = iterator.next() {
switch piece {
case .docLineComment, .docBlockComment,
.carriageReturns, .carriageReturnLineFeeds, .newlines, .spaces:
.carriageReturns, .carriageReturnLineFeeds, .newlines, .spaces:
break
case .lineComment, .blockComment:
@@ -65,8 +65,8 @@ private extension PrivateSwiftUIStatePropertyRule {
override func visitPost(_ node: VariableDeclSyntax) {
guard node.parent?.is(MemberBlockItemSyntax.self) == true,
swiftUITypeScopes.peek() ?? false,
node.containsSwiftUIStateAccessLevelViolation
swiftUITypeScopes.peek() ?? false,
node.containsSwiftUIStateAccessLevelViolation
else {
return
}
@@ -102,8 +102,8 @@ private extension PrivateSwiftUIStatePropertyRule {
override func visitPost(_ node: Syntax) {
if node.is(ClassDeclSyntax.self) ||
node.is(StructDeclSyntax.self) ||
node.is(ActorDeclSyntax.self) {
node.is(StructDeclSyntax.self) ||
node.is(ActorDeclSyntax.self) {
swiftUITypeScopes.pop()
}
}
@@ -44,12 +44,12 @@ struct QuickDiscouragedCallRule: OptInRule {
kind: SwiftExpressionKind,
dictionary: SourceKittenDictionary) -> [StyleViolation] {
// is it a call to a restricted method?
guard
kind == .call,
let name = dictionary.name,
let kindName = QuickCallKind(rawValue: name),
QuickCallKind.restrictiveKinds.contains(kindName)
else { return [] }
guard kind == .call,
let name = dictionary.name,
let kindName = QuickCallKind(rawValue: name),
QuickCallKind.restrictiveKinds.contains(kindName) else {
return []
}
return violationOffsets(in: dictionary.enclosedArguments).map {
StyleViolation(ruleDescription: Self.description,
@@ -73,29 +73,30 @@ struct QuickDiscouragedCallRule: OptInRule {
}
private func toViolationOffsets(dictionary: SourceKittenDictionary) -> [ByteCount] {
guard
dictionary.kind != nil,
let offset = dictionary.offset
else { return [] }
guard dictionary.kind != nil,
let offset = dictionary.offset else {
return []
}
if dictionary.expressionKind == .call,
let name = dictionary.name, QuickCallKind(rawValue: name) == nil {
let name = dictionary.name, QuickCallKind(rawValue: name) == nil {
return [offset]
}
guard dictionary.expressionKind != .call else { return [] }
guard dictionary.expressionKind != .call else {
return []
}
return dictionary.substructure.compactMap(toViolationOffset)
}
private func toViolationOffset(dictionary: SourceKittenDictionary) -> ByteCount? {
guard
let name = dictionary.name,
let offset = dictionary.offset,
dictionary.expressionKind == .call,
QuickCallKind(rawValue: name) == nil
else { return nil }
guard let name = dictionary.name,
let offset = dictionary.offset,
dictionary.expressionKind == .call,
QuickCallKind(rawValue: name) == nil else {
return nil
}
return offset
}
}
@@ -57,10 +57,10 @@ private extension TriviaPiece {
for todoKeywords: [TodoConfiguration.TodoKeyword]) -> [ReasonedRuleViolation] {
switch self {
case
.blockComment(let comment),
.lineComment(let comment),
.docBlockComment(let comment),
.docLineComment(let comment):
.blockComment(let comment),
.lineComment(let comment),
.docBlockComment(let comment),
.docLineComment(let comment):
// Construct a regex string considering only keywords.
let searchKeywords = todoKeywords.map(\.rawValue).joined(separator: "|")
@@ -52,14 +52,14 @@ struct TypesafeArrayInitRule: AnalyzerRule {
private static let parentRule = ArrayInitRule()
private static let mapTypePatterns = [
regex("""
\\Q<Self, T where Self : \\E(?:Sequence|Collection)> \
\\Q(Self) -> ((Self.Element) throws -> T) throws -> [T]\\E
"""),
regex("""
\\Q<Self, T, E where Self : \\E(?:Sequence|Collection), \
\\QE : Error> (Self) -> ((Self.Element) throws(E) -> T) throws(E) -> [T]\\E
"""),
regex("""
\\Q<Self, T where Self : \\E(?:Sequence|Collection)> \
\\Q(Self) -> ((Self.Element) throws -> T) throws -> [T]\\E
"""),
regex("""
\\Q<Self, T, E where Self : \\E(?:Sequence|Collection), \
\\QE : Error> (Self) -> ((Self.Element) throws(E) -> T) throws(E) -> [T]\\E
"""),
]
func validate(file: SwiftLintFile, compilerArguments: [String]) -> [StyleViolation] {
@@ -96,7 +96,7 @@ private extension OverridableDecl {
}
guard let call = extractFunctionCallSyntax(statement.item),
let member = call.calledExpression.as(MemberAccessExprSyntax.self),
let member = call.calledExpression.as(MemberAccessExprSyntax.self),
member.base?.is(SuperExprSyntax.self) == true,
member.declName.baseName.text == name else {
return false
@@ -161,9 +161,9 @@ private extension SwiftLintFile {
// Skip CodingKeys as they are used for Codable generation
if kind == .enum,
indexEntity.name == "CodingKeys",
case let allRelatedUSRs = indexEntity.traverseEntitiesDepthFirst(traverseBlock: { $1.usr }),
allRelatedUSRs.contains("s:s9CodingKeyP") {
indexEntity.name == "CodingKeys",
case let allRelatedUSRs = indexEntity.traverseEntitiesDepthFirst(traverseBlock: { $1.usr }),
allRelatedUSRs.contains("s:s9CodingKeyP") {
return nil
}
@@ -263,8 +263,8 @@ private extension SourceKittenDictionary {
func propertyAtOffset<T>(_ offset: ByteCount, property: KeyPath<Self, T?>) -> T? {
if let nameOffset,
nameOffset == offset,
let field = self[keyPath: property] {
nameOffset == offset,
let field = self[keyPath: property] {
return field
}
for child in substructure {
@@ -179,7 +179,7 @@ private extension SwiftLintFile {
if nextIsModuleImport {
nextIsModuleImport = false
if let importedModule = cursorInfo.moduleName,
cursorInfo.kind == "source.lang.swift.ref.module" {
cursorInfo.kind == "source.lang.swift.ref.module" {
imports.insert(importedModule)
continue
}
@@ -207,7 +207,7 @@ private extension SwiftLintFile {
// Operators are omitted in the editor.open request and thus have to be looked up by the indexsource request
func operatorImports(arguments: [String], processedTokenOffsets: Set<ByteCount>) -> Set<String> {
guard let index = (try? Request.index(file: path!, arguments: arguments).sendIfNotDisabled())
.map(SourceKittenDictionary.init) else {
.map(SourceKittenDictionary.init) else {
Issue.indexingError(path: path, ruleID: UnusedImportRule.identifier).print()
return []
}
@@ -230,7 +230,7 @@ private extension SwiftLintFile {
file: path!, offset: ByteCount(offset), arguments: arguments
)
guard let cursorInfo = (try? cursorInfoRequest.sendIfNotDisabled())
.map(SourceKittenDictionary.init) else {
.map(SourceKittenDictionary.init) else {
Issue.missingCursorInfo(path: path, ruleID: UnusedImportRule.identifier).print()
continue
}
@@ -142,7 +142,7 @@ private extension UnusedSetterValueRule {
let visitor = NewValueUsageVisitor(variableName: variableName)
if !visitor.walk(tree: node, handler: \.isVariableUsed) {
if Syntax(node).closestVariableOrSubscript()?.modifiers?.contains(keyword: .override) == true,
let body = node.body, body.statements.isEmpty {
let body = node.body, body.statements.isEmpty {
return
}
@@ -74,8 +74,8 @@ private extension WeakDelegateRule {
override func visitPost(_ node: VariableDeclSyntax) {
guard node.hasDelegateSuffix,
node.weakOrUnownedModifier == nil,
!node.hasComputedBody,
!node.containsIgnoredAttribute,
!node.hasComputedBody,
!node.containsIgnoredAttribute,
let parent = node.parent,
Syntax(parent).enclosingClass() != nil else {
return
@@ -89,9 +89,9 @@ private extension YodaConditionRule {
let lhs = children[lhsIdx]
if lhs.isLiteral,
children.startIndex == lhsIdx || children[children.index(before: lhsIdx)].isLogicalBinaryOperator {
// Literal is at the very beginning of the expression or the previous token is an operator with
// weaker binding. Thus, the literal is unique on the left-hand side of the comparison operator.
violations.append(lhs.positionAfterSkippingLeadingTrivia)
// Literal is at the very beginning of the expression or the previous token is an operator with
// weaker binding. Thus, the literal is unique on the left-hand side of the comparison operator.
violations.append(lhs.positionAfterSkippingLeadingTrivia)
}
}
}
@@ -147,7 +147,7 @@ private extension LineLengthRule {
// Check if line starts with comment markers
if lineContent.hasPrefix("//") || lineContent.hasPrefix("/*") ||
(lineContent.hasPrefix("*/") && lineContent.count == 2) {
(lineContent.hasPrefix("*/") && lineContent.count == 2) {
// Now verify using SwiftSyntax that this line doesn't contain any tokens
var hasNonCommentContent = false
@@ -225,7 +225,7 @@ private final class MultilineStringLiteralVisitor: SyntaxVisitor {
override func visitPost(_ node: StringLiteralExprSyntax) {
guard node.openingQuote.tokenKind == .multilineStringQuote ||
(node.openingPounds != nil && node.openingQuote.tokenKind == .stringQuote) else {
(node.openingPounds != nil && node.openingQuote.tokenKind == .stringQuote) else {
return
}
@@ -9,7 +9,7 @@ private func wrapExample(
file: StaticString = #filePath,
line: UInt = #line) -> Example {
Example("\(prefix)\(type) Abc {\n" +
repeatElement(template, count: count).joined() + "\(add)}\n", file: file, line: line)
repeatElement(template, count: count).joined() + "\(add)}\n", file: file, line: line)
}
@SwiftSyntaxRule
@@ -30,7 +30,7 @@ struct TypeBodyLengthRule: Rule {
]
}),
triggeringExamples: ["class", "struct", "enum", "actor"].map({ type in
wrapExample(prefix: "", type, "let abc = 0\n", 251)
wrapExample(prefix: "", type, "let abc = 0\n", 251)
})
)
}
@@ -56,8 +56,8 @@ private extension ExprSyntax {
return true
}
if let functionCall = self.as(FunctionCallExprSyntax.self),
let calledExpression = functionCall.calledExpression.as(DeclReferenceExprSyntax.self),
calledExpression.baseName.text == "NSPredicate" {
let calledExpression = functionCall.calledExpression.as(DeclReferenceExprSyntax.self),
calledExpression.baseName.text == "NSPredicate" {
return true
}
return false
@@ -52,8 +52,8 @@ private extension ExprSyntax {
return true
}
if let functionCall = self.as(FunctionCallExprSyntax.self),
let calledExpression = functionCall.calledExpression.as(DeclReferenceExprSyntax.self),
calledExpression.baseName.text == "NSPredicate" {
let calledExpression = functionCall.calledExpression.as(DeclReferenceExprSyntax.self),
calledExpression.baseName.text == "NSPredicate" {
return true
}
return false
@@ -152,8 +152,8 @@ private extension ExprSyntax {
return identifierExpr.isCopyOnWriteType
}
if let memberAccesExpr = expr.calledExpression.as(MemberAccessExprSyntax.self),
memberAccesExpr.declName.baseName.text == "init",
let identifierExpr = memberAccesExpr.base?.identifierExpr {
memberAccesExpr.declName.baseName.text == "init",
let identifierExpr = memberAccesExpr.base?.identifierExpr {
return identifierExpr.isCopyOnWriteType
}
if expr.calledExpression.isCopyOnWriteType {
@@ -162,7 +162,7 @@ private extension ExprSyntax {
}
return false
}
}
var identifierExpr: DeclReferenceExprSyntax? {
if let identifierExpr = self.as(DeclReferenceExprSyntax.self) {
@@ -102,14 +102,14 @@ struct DeploymentTargetConfiguration: SeverityBasedRuleConfiguration {
var parameterDescription: RuleConfigurationDescription? {
let targets = Dictionary(uniqueKeysWithValues: [
iOSDeploymentTarget,
iOSAppExtensionDeploymentTarget,
macOSDeploymentTarget,
macOSAppExtensionDeploymentTarget,
watchOSDeploymentTarget,
watchOSAppExtensionDeploymentTarget,
tvOSDeploymentTarget,
tvOSAppExtensionDeploymentTarget,
iOSDeploymentTarget,
iOSAppExtensionDeploymentTarget,
macOSDeploymentTarget,
macOSAppExtensionDeploymentTarget,
watchOSDeploymentTarget,
watchOSAppExtensionDeploymentTarget,
tvOSDeploymentTarget,
tvOSAppExtensionDeploymentTarget,
].map { ($0.platform.configurationKey, $0) })
severityConfiguration
for (platform, target) in targets.sorted(by: { $0.key < $1.key }) {
@@ -10,9 +10,9 @@ struct TransitiveModuleConfiguration<Parent: Rule>: Equatable, AcceptableByConfi
init(fromAny configuration: Any, context _: String) throws {
guard let configurationDict = configuration as? [String: Any],
Set(configurationDict.keys) == ["module", "allowed_transitive_imports"],
let importedModule = configurationDict["module"] as? String,
let transitivelyImportedModules = configurationDict["allowed_transitive_imports"] as? [String]
Set(configurationDict.keys) == ["module", "allowed_transitive_imports"],
let importedModule = configurationDict["module"] as? String,
let transitivelyImportedModules = configurationDict["allowed_transitive_imports"] as? [String]
else {
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
}
@@ -136,7 +136,7 @@ private extension TokenSyntax {
return true
}
if let previousToken = previousToken(viewMode: .sourceAccurate),
case .spaces(1) = Array(previousToken.trailingTrivia).last {
case .spaces(1) = Array(previousToken.trailingTrivia).last {
return true
}
return false
@@ -147,7 +147,7 @@ private extension TokenSyntax {
return true
}
if let nextToken = nextToken(viewMode: .sourceAccurate),
case .spaces(1) = nextToken.leadingTrivia.first {
case .spaces(1) = nextToken.leadingTrivia.first {
return true
}
return false
@@ -197,7 +197,7 @@ private extension TokenSyntax {
return true
}
if let nextToken = nextToken(viewMode: .sourceAccurate),
allowedKinds.contains(nextToken.tokenKind) {
allowedKinds.contains(nextToken.tokenKind) {
return true
}
return false
@@ -26,7 +26,7 @@ private extension CollectionAlignmentRule {
override func visitPost(_ node: DictionaryElementListSyntax) {
let locations = node.map { element in
let position = configuration.alignColons ? element.colon.positionAfterSkippingLeadingTrivia :
element.key.positionAfterSkippingLeadingTrivia
element.key.positionAfterSkippingLeadingTrivia
let location = locationConverter.location(for: position)
let graphemeColumn: Int
@@ -3,7 +3,7 @@ import SourceKittenFramework
import SwiftSyntax
struct CommaInheritanceRule: OptInRule, SubstitutionCorrectableRule,
SourceKitFreeRule {
SourceKitFreeRule {
var configuration = SeverityConfiguration<Self>(.warning)
static let description = RuleDescription(
@@ -80,7 +80,7 @@ private extension BracedSyntax {
}
if let closure = `as`(ClosureExprSyntax.self),
closure.keyPathInParent == \FunctionCallExprSyntax.trailingClosure {
return closure.leftBrace.previousIndentationDecidingToken
return closure.leftBrace.previousIndentationDecidingToken
}
if let closureLabel = parent?.as(MultipleTrailingClosureElementSyntax.self)?.label {
return closureLabel.previousIndentationDecidingToken
@@ -175,7 +175,7 @@ private extension ExprSyntax {
return nil
}
private func containsTrailingClosure(_ node: Syntax) -> Bool {
private func containsTrailingClosure(_ node: Syntax) -> Bool {
switch node.as(SyntaxEnum.self) {
case .functionCallExpr(let node):
node.trailingClosure != nil || node.calledExpression.is(ClosureExprSyntax.self)
@@ -119,10 +119,10 @@ private extension StringView {
func recursiveByteOffsets(_ dict: [String: Any]) -> [ByteCount] {
let cur: [ByteCount]
if let line = dict["key.line"] as? Int64,
let column = dict["key.column"] as? Int64,
let kindString = dict["key.kind"] as? String,
kindsToFind.contains(kindString),
let offset = byteOffset(forLine: line, bytePosition: column) {
let column = dict["key.column"] as? Int64,
let kindString = dict["key.kind"] as? String,
kindsToFind.contains(kindString),
let offset = byteOffset(forLine: line, bytePosition: column) {
cur = [offset]
} else {
cur = []
@@ -40,9 +40,9 @@ struct LeadingWhitespaceRule: CorrectableRule, SourceKitFreeRule {
let whitespaceAndNewline = CharacterSet.whitespacesAndNewlines
let spaceCount = file.contents.countOfLeadingCharacters(in: whitespaceAndNewline)
guard spaceCount > 0,
let firstLineRange = file.lines.first?.range,
file.ruleEnabled(violatingRanges: [firstLineRange], for: self).isNotEmpty else {
return 0
let firstLineRange = file.lines.first?.range,
file.ruleEnabled(violatingRanges: [firstLineRange], for: self).isNotEmpty else {
return 0
}
let indexEnd = file.contents.index(
@@ -220,17 +220,17 @@ extension LiteralExpressionEndIndentationRule {
let contents = file.stringView
guard elements.isNotEmpty,
let offset = dictionary.offset,
let length = dictionary.length,
let (startLine, _) = contents.lineAndCharacter(forByteOffset: offset),
let firstParamOffset = elements[0].offset,
let (firstParamLine, _) = contents.lineAndCharacter(forByteOffset: firstParamOffset),
startLine != firstParamLine,
let lastParamOffset = elements.last?.offset,
let (lastParamLine, _) = contents.lineAndCharacter(forByteOffset: lastParamOffset),
case let endOffset = offset + length - 1,
let (endLine, endPosition) = contents.lineAndCharacter(forByteOffset: endOffset),
lastParamLine != endLine
let offset = dictionary.offset,
let length = dictionary.length,
let (startLine, _) = contents.lineAndCharacter(forByteOffset: offset),
let firstParamOffset = elements[0].offset,
let (firstParamLine, _) = contents.lineAndCharacter(forByteOffset: firstParamOffset),
startLine != firstParamLine,
let lastParamOffset = elements.last?.offset,
let (lastParamLine, _) = contents.lineAndCharacter(forByteOffset: lastParamOffset),
case let endOffset = offset + length - 1,
let (endLine, endPosition) = contents.lineAndCharacter(forByteOffset: endOffset),
lastParamLine != endLine
else {
return nil
}
@@ -239,8 +239,8 @@ extension LiteralExpressionEndIndentationRule {
let regex = Self.notWhitespace
let actual = endPosition - 1
guard let match = regex.firstMatch(in: file.contents, options: [], range: range)?.range,
case let expected = match.location - range.location,
expected != actual
case let expected = match.location - range.location,
expected != actual
else {
return nil
}
@@ -108,10 +108,9 @@ struct MultilineFunctionChainsRule: ASTRule, OptInRule {
let ranges = callRanges(file: file, kind: kind, dictionary: dictionary)
let calls = ranges.compactMap { range -> (dotLine: Int, dotOffset: Int, range: ByteRange)? in
guard
let offset = callDotOffset(file: file, callRange: range),
let line = file.stringView.lineAndCharacter(forCharacterOffset: offset)?.line else {
return nil
guard let offset = callDotOffset(file: file, callRange: range),
let line = file.stringView.lineAndCharacter(forCharacterOffset: offset)?.line else {
return nil
}
return (dotLine: line, dotOffset: offset, range: range)
}
@@ -133,11 +132,10 @@ struct MultilineFunctionChainsRule: ASTRule, OptInRule {
private static let whitespaceDotRegex = regex("\\s*\\.")
private func callDotOffset(file: SwiftLintFile, callRange: ByteRange) -> Int? {
guard
let range = file.stringView.byteRangeToNSRange(callRange),
case let regex = Self.whitespaceDotRegex,
let match = regex.matches(in: file.contents, options: [], range: range).last?.range else {
return nil
guard let range = file.stringView.byteRangeToNSRange(callRange),
case let regex = Self.whitespaceDotRegex,
let match = regex.matches(in: file.contents, options: [], range: range).last?.range else {
return nil
}
return match.location + match.length - 1
}
@@ -145,11 +143,10 @@ struct MultilineFunctionChainsRule: ASTRule, OptInRule {
private static let newlineWhitespaceDotRegex = regex("\\n\\s*\\.")
private func callHasLeadingNewline(file: SwiftLintFile, callRange: ByteRange) -> Bool {
guard
let range = file.stringView.byteRangeToNSRange(callRange),
case let regex = Self.newlineWhitespaceDotRegex,
regex.firstMatch(in: file.contents, options: [], range: range) != nil else {
return false
guard let range = file.stringView.byteRangeToNSRange(callRange),
case let regex = Self.newlineWhitespaceDotRegex,
regex.firstMatch(in: file.contents, options: [], range: range) != nil else {
return false
}
return true
}
@@ -189,17 +186,15 @@ struct MultilineFunctionChainsRule: ASTRule, OptInRule {
call: SourceKittenDictionary,
parentName: String,
parentNameOffset: ByteCount) -> ByteRange? {
guard
case let contents = file.stringView,
let nameOffset = call.nameOffset,
parentNameOffset == nameOffset,
let nameLength = call.nameLength,
let bodyOffset = call.bodyOffset,
let bodyLength = call.bodyLength,
case let nameByteRange = ByteRange(location: nameOffset, length: nameLength),
let name = contents.substringWithByteRange(nameByteRange),
parentName.starts(with: name)
else {
guard case let contents = file.stringView,
let nameOffset = call.nameOffset,
parentNameOffset == nameOffset,
let nameLength = call.nameLength,
let bodyOffset = call.bodyOffset,
let bodyLength = call.bodyLength,
case let nameByteRange = ByteRange(location: nameOffset, length: nameLength),
let name = contents.substringWithByteRange(nameByteRange),
parentName.starts(with: name) else {
return nil
}
@@ -145,7 +145,7 @@ private extension MultilineLiteralBracketsRule {
firstElement: (some ExprSyntaxProtocol)?,
lastElement: (some ExprSyntaxProtocol)?) {
guard let firstElement, let lastElement,
isMultiline(node) else {
isMultiline(node) else {
return
}
@@ -99,7 +99,7 @@ struct MultilineParametersBracketsRule: OptInRule {
// find violations at current level
if let kind = substructure.declarationKind,
SwiftDeclarationKind.functionKinds.contains(kind) {
SwiftDeclarationKind.functionKinds.contains(kind) {
guard
let nameOffset = substructure.nameOffset,
let nameLength = substructure.nameLength,
@@ -104,15 +104,15 @@ private extension NumberSeparatorValidator {
func violation(token: TokenSyntax) -> NumberSeparatorViolation? {
let content = token.text
guard isDecimal(number: content),
!isInValidRanges(number: content)
!isInValidRanges(number: content)
else {
return nil
}
let exponential = CharacterSet(charactersIn: "eE")
guard case let exponentialComponents = content.components(separatedBy: exponential),
let nonExponential = exponentialComponents.first else {
return nil
let nonExponential = exponentialComponents.first else {
return nil
}
let components = nonExponential.components(separatedBy: ".")
@@ -124,8 +124,8 @@ private extension NumberSeparatorValidator {
}
guard let integerSubstring = components.first,
case let (valid, expected) = isValid(number: integerSubstring, isFraction: false),
!valid || !validFraction
case let (valid, expected) = isValid(number: integerSubstring, isFraction: false),
!valid || !validFraction
else {
return nil
}
@@ -29,7 +29,7 @@ private extension OpeningBraceRule {
override func visitPost(_ node: ActorDeclSyntax) {
if configuration.ignoreMultilineTypeHeaders,
hasMultilinePredecessors(node.memberBlock, keyword: node.actorKeyword) {
hasMultilinePredecessors(node.memberBlock, keyword: node.actorKeyword) {
return
}
@@ -38,7 +38,7 @@ private extension OpeningBraceRule {
override func visitPost(_ node: ClassDeclSyntax) {
if configuration.ignoreMultilineTypeHeaders,
hasMultilinePredecessors(node.memberBlock, keyword: node.classKeyword) {
hasMultilinePredecessors(node.memberBlock, keyword: node.classKeyword) {
return
}
@@ -47,7 +47,7 @@ private extension OpeningBraceRule {
override func visitPost(_ node: EnumDeclSyntax) {
if configuration.ignoreMultilineTypeHeaders,
hasMultilinePredecessors(node.memberBlock, keyword: node.enumKeyword) {
hasMultilinePredecessors(node.memberBlock, keyword: node.enumKeyword) {
return
}
@@ -56,7 +56,7 @@ private extension OpeningBraceRule {
override func visitPost(_ node: ExtensionDeclSyntax) {
if configuration.ignoreMultilineTypeHeaders,
hasMultilinePredecessors(node.memberBlock, keyword: node.extensionKeyword) {
hasMultilinePredecessors(node.memberBlock, keyword: node.extensionKeyword) {
return
}
@@ -65,7 +65,7 @@ private extension OpeningBraceRule {
override func visitPost(_ node: ProtocolDeclSyntax) {
if configuration.ignoreMultilineTypeHeaders,
hasMultilinePredecessors(node.memberBlock, keyword: node.protocolKeyword) {
hasMultilinePredecessors(node.memberBlock, keyword: node.protocolKeyword) {
return
}
@@ -74,7 +74,7 @@ private extension OpeningBraceRule {
override func visitPost(_ node: StructDeclSyntax) {
if configuration.ignoreMultilineTypeHeaders,
hasMultilinePredecessors(node.memberBlock, keyword: node.structKeyword) {
hasMultilinePredecessors(node.memberBlock, keyword: node.structKeyword) {
return
}
@@ -85,7 +85,7 @@ private extension OpeningBraceRule {
override func visitPost(_ node: ForStmtSyntax) {
if configuration.ignoreMultilineStatementConditions,
hasMultilinePredecessors(node.body, keyword: node.forKeyword) {
hasMultilinePredecessors(node.body, keyword: node.forKeyword) {
return
}
@@ -94,7 +94,7 @@ private extension OpeningBraceRule {
override func visitPost(_ node: IfExprSyntax) {
if configuration.ignoreMultilineStatementConditions,
hasMultilinePredecessors(node.body, keyword: node.ifKeyword) {
hasMultilinePredecessors(node.body, keyword: node.ifKeyword) {
return
}
@@ -103,7 +103,7 @@ private extension OpeningBraceRule {
override func visitPost(_ node: WhileStmtSyntax) {
if configuration.ignoreMultilineStatementConditions,
hasMultilinePredecessors(node.body, keyword: node.whileKeyword) {
hasMultilinePredecessors(node.body, keyword: node.whileKeyword) {
return
}
@@ -114,8 +114,8 @@ private extension OpeningBraceRule {
override func visitPost(_ node: FunctionDeclSyntax) {
if let body = node.body,
configuration.shouldIgnoreMultilineFunctionSignatures,
hasMultilinePredecessors(body, keyword: node.funcKeyword) {
configuration.shouldIgnoreMultilineFunctionSignatures,
hasMultilinePredecessors(body, keyword: node.funcKeyword) {
return
}
@@ -124,8 +124,8 @@ private extension OpeningBraceRule {
override func visitPost(_ node: InitializerDeclSyntax) {
if let body = node.body,
configuration.shouldIgnoreMultilineFunctionSignatures,
hasMultilinePredecessors(body, keyword: node.initKeyword) {
configuration.shouldIgnoreMultilineFunctionSignatures,
hasMultilinePredecessors(body, keyword: node.initKeyword) {
return
}
@@ -68,9 +68,9 @@ struct OperatorUsageWhitespaceRule: OptInRule, CorrectableRule, SourceKitFreeRul
let equalityOperatorRegex = regex("\\s+=\\s")
guard let match = equalityOperatorRegex.firstMatch(
in: matchedString,
options: [],
range: matchedString.fullNSRange),
in: matchedString,
options: [],
range: matchedString.fullNSRange),
match.range == matchedString.fullNSRange
else {
return false
@@ -91,8 +91,8 @@ private extension SelfBindingRule {
return super.visit(node.with(\.pattern, newPattern))
}
if node.initializer == nil,
identifierPattern.identifier.text == "self",
configuration.bindIdentifier != "self" {
identifierPattern.identifier.text == "self",
configuration.bindIdentifier != "self" {
numberOfCorrections += 1
let newPattern = PatternSyntax(
identifierPattern
@@ -103,7 +103,7 @@ private extension ShorthandArgumentRule {
if complexArguments.contains(argument) {
nil
} else if locationConverter.location(for: argument.position).line
<= startLine + configuration.allowUntilLineAfterOpeningBrace {
<= startLine + configuration.allowUntilLineAfterOpeningBrace {
nil
} else {
ReasonedRuleViolation(
@@ -84,8 +84,9 @@ struct SortedImportsRule: CorrectableRule, OptInRule {
let contents = file.stringView
let lines = file.lines
let importLines: [Line] = importRanges.compactMap { range in
guard let line = contents.lineAndCharacter(forCharacterOffset: range.location)?.line
else { return nil }
guard let line = contents.lineAndCharacter(forCharacterOffset: range.location)?.line else {
return nil
}
return lines[line - 1]
}
@@ -184,7 +184,7 @@ private extension StatementPositionRule {
let validator = Self.uncuddledMatchValidator(contents: file.stringView)
let filterRanges = Self.uncuddledMatchFilter(contents: file.stringView, syntaxMap: syntaxMap)
let validMatches = matches.compactMap(validator).filter(filterRanges)
.filter { file.ruleEnabled(violatingRanges: [$0.range], for: self).isNotEmpty }
.filter { file.ruleEnabled(violatingRanges: [$0.range], for: self).isNotEmpty }
if validMatches.isEmpty {
return 0
}
@@ -195,7 +195,7 @@ private extension StatementPositionRule {
var whitespace = contents.bridge().substring(with: range1)
let newLines: String
if newlineRange.location != NSNotFound {
newLines = contents.bridge().substring(with: newlineRange)
newLines = contents.bridge().substring(with: newlineRange)
} else {
newLines = ""
}
@@ -154,7 +154,7 @@ private extension TrailingCommaRule {
.with(\.expression, lastElement.expression.with(\.trailingTrivia, []))
.with(\.trailingComma, .commaToken())
.with(\.trailingTrivia, lastElement.expression.trailingTrivia)
)
)
return super.visit(newNode)
case (_, true), (nil, false):
return super.visit(node)
@@ -49,7 +49,7 @@ private extension TrailingWhitespaceRule {
// Apply `ignoresEmptyLines` configuration
if configuration.ignoresEmptyLines &&
line.trimmingCharacters(in: .whitespaces).isEmpty {
line.trimmingCharacters(in: .whitespaces).isEmpty {
continue
}
@@ -148,7 +148,7 @@ struct VerticalWhitespaceBetweenCasesRule: Rule {
let patternRegex = regex(pattern)
let substring = file.contents.substring(from: range.location, length: range.length)
guard let matchResult = patternRegex.firstMatch(in: substring, options: [], range: substring.fullNSRange),
matchResult.numberOfRanges > 1 else {
matchResult.numberOfRanges > 1 else {
return false
}
@@ -127,7 +127,7 @@ public struct SourceKittenDictionary {
public var elements: [Self] {
let elements = value["key.elements"] as? [any SourceKitRepresentable] ?? []
return elements.compactMap { $0 as? [String: any SourceKitRepresentable] }
.map(Self.init)
.map(Self.init)
}
public var entities: [Self] {
@@ -22,7 +22,7 @@ public extension Request {
// Skip check for ConditionallySourceKitFree rules since we can't determine
// at the type level if they're effectively SourceKit-free
if ruleType is any SourceKitFreeRule.Type &&
!(ruleType is any ConditionallySourceKitFree.Type) {
!(ruleType is any ConditionallySourceKitFree.Type) {
queuedFatalError("""
'\(ruleID)' is a SourceKitFreeRule and should not be making requests to SourceKit.
""")
@@ -55,8 +55,8 @@ public extension String {
limitedBy: utf16.endIndex) ?? utf16.endIndex
guard let fromIndex = Index(from16, within: self),
let toIndex = Index(to16, within: self) else {
return nil
let toIndex = Index(to16, within: self) else {
return nil
}
return fromIndex..<toIndex
@@ -159,7 +159,7 @@ extension SwiftLintFile {
let tokenRange = token.range
if line.byteRange.contains(token.offset) ||
tokenRange.contains(line.byteRange.location) {
results[line.index].append(token)
results[line.index].append(token)
}
let tokenEnd = tokenRange.upperBound
let lineEnd = line.byteRange.upperBound
@@ -66,8 +66,8 @@ public extension ExprSyntax {
return functionCall
}
if let tuple = self.as(TupleExprSyntax.self),
let firstElement = tuple.elements.onlyElement,
let functionCall = firstElement.expression.as(FunctionCallExprSyntax.self) {
let firstElement = tuple.elements.onlyElement,
let functionCall = firstElement.expression.as(FunctionCallExprSyntax.self) {
return functionCall
}
return nil
+3 -4
View File
@@ -105,10 +105,9 @@ public struct Baseline: Equatable {
var filteredViolations: Set<BaselineViolation> = []
for (ruleIdentifier, ruleViolations) in violationsByRuleIdentifier {
guard
let baselineViolations = baselineViolationsByRuleIdentifier[ruleIdentifier],
baselineViolations.isNotEmpty else {
filteredViolations.formUnion(ruleViolations)
guard let baselineViolations = baselineViolationsByRuleIdentifier[ruleIdentifier],
baselineViolations.isNotEmpty else {
filteredViolations.formUnion(ruleViolations)
continue
}
@@ -24,7 +24,7 @@ public struct ChildOptionSeverityConfiguration<Parent: Rule>: RuleConfiguration,
public mutating func apply(configuration: Any) throws {
guard let configString = configuration as? String,
let optionSeverity = ChildOptionSeverity(rawValue: configString.lowercased()) else {
let optionSeverity = ChildOptionSeverity(rawValue: configString.lowercased()) else {
throw Issue.invalidConfiguration(ruleID: Parent.identifier)
}
self.optionSeverity = optionSeverity
+3 -3
View File
@@ -109,9 +109,9 @@ public struct Command: Equatable {
// Store any text after the comment delimiter as the trailingComment.
// The addition to currentIndex is to move past the delimiter
trailingComment = String(
scanner
.string[scanner.currentIndex...]
.dropFirst(Self.commentDelimiter.count)
scanner
.string[scanner.currentIndex...]
.dropFirst(Self.commentDelimiter.count)
)
}
let ruleTexts = rawRuleTexts.components(separatedBy: .whitespacesAndNewlines).filter {
@@ -11,7 +11,7 @@ public struct RuleDescription: Equatable, Sendable {
/// explanation of the rule's purpose and rationale.
public let description: String
/// A longer explanation of the rule's purpose and rationale. Typically defined as a multiline string, long text
/// A longer explanation of the rule's purpose and rationale. Typically defined as a multiline string, long text
/// lines should be wrapped. Markdown formatting is supported. Multiline code blocks will be formatted as
/// `swift` code unless otherwise specified, and will automatically be indented by four spaces when printed
/// to the console.
@@ -92,7 +92,7 @@ public extension SwiftVersion {
try? Request.customRequest(request: params).sendIfNotDisabled()
}
if let result,
let major = result.versionMajor, let minor = result.versionMinor, let patch = result.versionPatch {
let major = result.versionMajor, let minor = result.versionMinor, let patch = result.versionPatch {
return SwiftVersion(rawValue: "\(major).\(minor).\(patch)")
}
}
+11 -11
View File
@@ -28,7 +28,7 @@ public protocol Rule {
/// Create a description of how this rule has been configured to run.
///
/// - parameter exclusiveOptions: A set of options that should be excluded from the description.
///
///
/// - returns: A description of the rule's configuration.
func createConfigurationDescription(exclusiveOptions: Set<String>) -> RuleConfigurationDescription
@@ -83,17 +83,17 @@ public protocol Rule {
/// - ruleID: The name of a rule as used in a disable command.
///
/// - Returns: A boolean value indicating whether the violation can be disabled by the given ID.
func canBeDisabled(violation: StyleViolation, by ruleID: RuleIdentifier) -> Bool
func canBeDisabled(violation: StyleViolation, by ruleID: RuleIdentifier) -> Bool
/// Checks if a the rule is enabled in a given region. A specific rule ID can be provided in case a rule supports
/// more than one identifier.
///
/// - Parameters:
/// - region: The region to check.
/// - ruleID: Rule identifier deviating from the default rule's name.
///
/// - Returns: A boolean value indicating whether the rule is enabled in the given region.
func isEnabled(in region: Region, for ruleID: String) -> Bool
/// Checks if a the rule is enabled in a given region. A specific rule ID can be provided in case a rule supports
/// more than one identifier.
///
/// - Parameters:
/// - region: The region to check.
/// - ruleID: Rule identifier deviating from the default rule's name.
///
/// - Returns: A boolean value indicating whether the rule is enabled in the given region.
func isEnabled(in region: Region, for ruleID: String) -> Bool
}
public extension Rule {
@@ -50,8 +50,8 @@ public struct RegexConfiguration<Parent: Rule>: SeverityBasedRuleConfiguration,
executionMode.rawValue,
]
if let jsonData = try? JSONSerialization.data(withJSONObject: jsonObject),
let jsonString = String(data: jsonData, encoding: .utf8) {
return jsonString
let jsonString = String(data: jsonData, encoding: .utf8) {
return jsonString
}
queuedFatalError("Could not serialize regex configuration for cache")
}
@@ -32,7 +32,7 @@ open class CodeBlockVisitor<Configuration: RuleConfiguration>: ViolationsSyntaxV
return
}
if parent.is(FunctionCallExprSyntax.self) || parent.is(MultipleTrailingClosureElementSyntax.self),
node.keyPathInParent != \FunctionCallExprSyntax.calledExpression {
node.keyPathInParent != \FunctionCallExprSyntax.calledExpression {
// Trailing closure
collectViolations(for: node)
}
@@ -66,8 +66,8 @@ extension Array where Element == String {
let responseFile = String(arg.dropFirst())
return (try? String(contentsOf: URL(fileURLWithPath: responseFile, isDirectory: false))).flatMap {
$0.trimmingCharacters(in: .newlines)
.components(separatedBy: "\n")
.expandingResponseFiles
.components(separatedBy: "\n")
.expandingResponseFiles
} ?? [arg]
}
}
@@ -273,8 +273,8 @@ extension Configuration {
queuedPrintError("\(options.capitalizedVerb) Swift files \(filesInfo)")
}
let excludeLintableFilesBy = options.useExcludingByPrefix
? Configuration.ExcludeBy.prefix
: .paths(excludedPaths: excludedPaths())
? Configuration.ExcludeBy.prefix
: .paths(excludedPaths: excludedPaths())
return options.paths.flatMap {
self.lintableFiles(
inPath: $0,
@@ -171,8 +171,8 @@ extension Configuration {
) {
for key in dict.keys where !validGlobalKeys.contains(key) {
guard let identifier = ruleList.identifier(for: key),
let ruleType = ruleList.list[identifier] else {
continue
let ruleType = ruleList.list[identifier] else {
continue
}
switch rulesMode {
@@ -131,7 +131,7 @@ package struct LintOrAnalyzeCommand {
Could not change working directory to '\(workingDirectory)'. \
Make sure it exists and is accessible.
"""
)
)
}
}
try await Signposts.record(name: "LintOrAnalyzeCommand.run") {
@@ -236,9 +236,8 @@ package struct LintOrAnalyzeCommand {
return try Baseline(fromPath: baselinePath)
} catch {
Issue.baselineNotReadable(path: baselinePath).print()
if
(error as? CocoaError)?.code != CocoaError.fileReadNoSuchFile ||
options.writeBaseline != options.baseline {
if (error as? CocoaError)?.code != CocoaError.fileReadNoSuchFile ||
options.writeBaseline != options.baseline {
throw error
}
}
@@ -142,7 +142,7 @@ struct LintableFilesVisitor {
private static func loadLogCompilerInvocations(_ path: String) -> [[String]]? {
if let data = FileManager.default.contents(atPath: path),
let logContents = String(data: data, encoding: .utf8) {
let logContents = String(data: data, encoding: .utf8) {
if logContents.isEmpty {
return nil
}
@@ -164,7 +164,7 @@ struct LintableFilesVisitor {
}
guard let object = try? JSONSerialization.jsonObject(with: fileContents),
let compileDB = object as? [[String: Any]] else {
let compileDB = object as? [[String: Any]] else {
throw CompileCommandsLoadError.malformedCommands(path)
}
@@ -373,7 +373,7 @@ public struct CollectedLinter {
private func cachedStyleViolations(benchmark: Bool = false) -> ([StyleViolation], [(id: String, time: Double)])? {
let start = Date()
guard let cache, let file = file.path,
let cachedViolations = cache.violations(forFile: file, configuration: configuration) else {
let cachedViolations = cache.violations(forFile: file, configuration: configuration) else {
return nil
}
@@ -74,9 +74,9 @@ public final class LinterCache {
internal func violations(forFile file: String, configuration: Configuration) -> [StyleViolation]? {
guard let lastModification = fileManager.modificationDate(forFileAtPath: file),
let entry = fileCache(cacheDescription: configuration.cacheDescription).entries[file],
entry.lastModification == lastModification,
entry.swiftVersion == swiftVersion
let entry = fileCache(cacheDescription: configuration.cacheDescription).entries[file],
entry.lastModification == lastModification,
entry.swiftVersion == swiftVersion
else {
return nil
}
+1 -1
View File
@@ -384,7 +384,7 @@ final class CustomRulesTests: SwiftLintTestCase {
]
let example = Example(
"""
"""
// swiftlint:disable custom1 custom3
return 10
"""
+1 -1
View File
@@ -38,7 +38,7 @@ final class GlobTests: SwiftLintTestCase {
func testNoMatchOneCharacterInBracket() {
let files = Glob.resolveGlob(mockPath.stringByAppendingPathComponent("Level[ab].swift"))
XCTAssertTrue(files.isEmpty)
XCTAssertTrue(files.isEmpty)
}
func testMatchesCharacterInRange() {
+14 -14
View File
@@ -47,10 +47,10 @@ public let allRuleIdentifiers = Set(RuleRegistry.shared.list.list.keys)
public extension Configuration {
func applyingConfiguration(from example: Example) -> Configuration {
guard let exampleConfiguration = example.configuration,
case let .onlyConfiguration(onlyRules) = self.rulesMode,
let firstRule = (onlyRules.first { $0 != "superfluous_disable_command" }),
case let configDict: [_: any Sendable] = ["only_rules": onlyRules, firstRule: exampleConfiguration],
let typedConfiguration = try? Configuration(dict: configDict) else { return self }
case let .onlyConfiguration(onlyRules) = self.rulesMode,
let firstRule = (onlyRules.first { $0 != "superfluous_disable_command" }),
case let configDict: [_: any Sendable] = ["only_rules": onlyRules, firstRule: exampleConfiguration],
let typedConfiguration = try? Configuration(dict: configDict) else { return self }
return merged(withChild: typedConfiguration, rootDirectory: rootDirectory)
}
}
@@ -156,7 +156,7 @@ private func render(violations: [StyleViolation], in contents: String) -> String
var contents = StringView(contents).lines.map(\.content)
for violation in violations.sorted(by: { $0.location > $1.location }) {
guard let line = violation.location.line,
let character = violation.location.character else { continue }
let character = violation.location.character else { continue }
let message = String(repeating: " ", count: character - 1) + "^ " + [
"\(violation.severity.rawValue): ",
@@ -267,10 +267,10 @@ private func testCorrection(_ correction: (Example, Example),
#endif
var config = configuration
if let correctionConfiguration = correction.0.configuration,
case let .onlyConfiguration(onlyRules) = configuration.rulesMode,
let ruleToConfigure = (onlyRules.first { $0 != SuperfluousDisableCommandRule.identifier }),
case let configDict: [_: any Sendable] = ["only_rules": onlyRules, ruleToConfigure: correctionConfiguration],
let typedConfiguration = try? Configuration(dict: configDict) {
case let .onlyConfiguration(onlyRules) = configuration.rulesMode,
let ruleToConfigure = (onlyRules.first { $0 != SuperfluousDisableCommandRule.identifier }),
case let configDict: [_: any Sendable] = ["only_rules": onlyRules, ruleToConfigure: correctionConfiguration],
let typedConfiguration = try? Configuration(dict: configDict) {
config = configuration.merged(withChild: typedConfiguration, rootDirectory: configuration.rootDirectory)
}
@@ -307,11 +307,11 @@ public extension XCTestCase {
}
guard let config = makeConfig(
ruleConfiguration,
ruleDescription.identifier,
skipDisableCommandTests: skipDisableCommandTests) else {
XCTFail("Failed to create configuration", file: (file), line: line)
return
ruleConfiguration,
ruleDescription.identifier,
skipDisableCommandTests: skipDisableCommandTests) else {
XCTFail("Failed to create configuration", file: (file), line: line)
return
}
let disableCommands: [String]