Skip to content

Commit 354ee5a

Browse files
committed
Demote AvoidInitializersForLiterals to lint rule.
1 parent 8c75fba commit 354ee5a

File tree

3 files changed

+35
-69
lines changed

3 files changed

+35
-69
lines changed

Sources/SwiftFormatRules/AvoidInitializersForLiterals.swift

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,17 @@ fileprivate let knownIntTypes = Set(intSizes.map { "Int\($0)" } + intSizes.map {
2525
/// Lint: If an initializer-style cast is used on a built-in type known to be expressible by
2626
/// that kind of literal type, a lint error is raised.
2727
///
28-
/// Format: Initializer-style casts between known built-in types will be converted to standard
29-
/// casts.
30-
///
3128
/// - SeeAlso: https://google.github.io/swift#numeric-and-string-literals
32-
public final class AvoidInitializersForLiterals: SyntaxFormatRule {
33-
public override func visit(_ node: FunctionCallExprSyntax) -> ExprSyntax {
29+
public final class AvoidInitializersForLiterals: SyntaxLintRule {
30+
public override func visit(_ node: FunctionCallExprSyntax) {
3431
// Ensure we're calling a known Integer initializer.
3532
guard let callee = node.calledExpression as? IdentifierExprSyntax else {
3633
// Ensure we properly visit the children of this node, in case we have other function calls
3734
// as parameters to this one.
3835
return super.visit(node)
3936
}
4037

41-
guard node.argumentList.count <= 1 else {
38+
guard node.argumentList.count == 1 else {
4239
return super.visit(node)
4340
}
4441

@@ -50,44 +47,13 @@ public final class AvoidInitializersForLiterals: SyntaxFormatRule {
5047

5148
let typeName = callee.identifier.text
5249

53-
guard let literal = extractLiteral(node, typeName) else {
50+
guard let _ = extractLiteral(node, typeName) else {
5451
return super.visit(node)
5552
}
5653

57-
diagnose(.avoidInitializerStyleCast, on: callee) {
54+
diagnose(.avoidInitializerStyleCast(node.description), on: callee) {
5855
$0.highlight(callee.sourceRange(in: self.context.fileURL))
5956
}
60-
61-
// Construct an 'as' cast, converting `X(y)` to `y as X`.
62-
let asExpr = AsExprSyntax {
63-
$0.useAsTok(SyntaxFactory.makeAsKeyword(
64-
trailingTrivia: .spaces(1)
65-
))
66-
$0.useTypeName(
67-
SyntaxFactory.makeSimpleTypeIdentifier(
68-
name: callee.identifier,
69-
genericArgumentClause: nil
70-
)
71-
)
72-
}
73-
74-
let newAs = replaceTrivia(
75-
on: asExpr,
76-
token: asExpr.lastToken,
77-
trailingTrivia: node.trailingTrivia
78-
) as! AsExprSyntax
79-
80-
let newLiteral = replaceTrivia(
81-
on: literal,
82-
token: literal.firstToken,
83-
trailingTrivia: .spaces(1)
84-
) as! ExprSyntax
85-
86-
return SyntaxFactory.makeSequenceExpr(
87-
elements: SyntaxFactory.makeExprList([
88-
newLiteral,
89-
newAs
90-
]))
9157
}
9258
}
9359

@@ -105,6 +71,7 @@ fileprivate func extractLiteral(_ node: FunctionCallExprSyntax, _ typeName: Stri
10571
}
10672

10773
extension Diagnostic.Message {
108-
static let avoidInitializerStyleCast =
109-
Diagnostic.Message(.warning, "change initializer call with literal argument to an 'as' cast")
74+
static func avoidInitializerStyleCast(_ name: String) -> Diagnostic.Message {
75+
return .init(.warning, "change initializer call '\(name)' with literal argument to an 'as' cast")
76+
}
11077
}

Sources/swift-format/PopulatePipeline.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@ func populate(_ pipeline: Pipeline) {
2727

2828
/// MARK: Formatting Passes
2929

30-
pipeline.addFormatter(
31-
AvoidInitializersForLiterals.self,
32-
for:
33-
FunctionCallExprSyntax.self
34-
)
35-
3630
pipeline.addFormatter(
3731
BlankLineBetweenMembers.self,
3832
for:
@@ -278,6 +272,12 @@ func populate(_ pipeline: Pipeline) {
278272
SourceFileSyntax.self
279273
)
280274

275+
pipeline.addLinter(
276+
AvoidInitializersForLiterals.self,
277+
for:
278+
FunctionCallExprSyntax.self
279+
)
280+
281281
pipeline.addLinter(
282282
BeginDocumentationCommentWithOneLineSummary.self,
283283
for:

Tests/SwiftFormatRulesTests/AvoidInitializersForLiteralsTests.swift

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,27 @@ import XCTest
55

66
public class AvoidInitializersForLiteralsTests: DiagnosingTestCase {
77
public func testInitializersForLiterals() {
8-
XCTAssertFormatting(
9-
AvoidInitializersForLiterals.self,
10-
input: """
11-
let v1 = UInt32(76)
12-
let v2 = UInt8(257)
13-
performFunction(x: Int16(54))
14-
performFunction(x: Int32(54))
15-
performFunction(x: Int64(54))
16-
let c = Character("s")
17-
if 3 > Int(2) || someCondition {}
18-
let a = Int(bitPattern: 123456)
19-
""",
20-
expected: """
21-
let v1 = 76 as UInt32
22-
let v2 = 257 as UInt8
23-
performFunction(x: 54 as Int16)
24-
performFunction(x: 54 as Int32)
25-
performFunction(x: 54 as Int64)
26-
let c = "s" as Character
27-
if 3 > 2 as Int || someCondition {}
28-
let a = Int(bitPattern: 123456)
29-
""")
8+
let input =
9+
"""
10+
let v1 = UInt32(76)
11+
let v2 = UInt8(257)
12+
performFunction(x: Int16(54))
13+
performFunction(x: Int32(54))
14+
performFunction(x: Int64(54))
15+
let c = Character("s")
16+
if 3 > Int(2) || someCondition {}
17+
let a = Int(bitPattern: 123456)
18+
"""
19+
20+
performLint(AvoidInitializersForLiterals.self, input: input)
21+
XCTAssertDiagnosed(.avoidInitializerStyleCast("UInt32(76)"))
22+
XCTAssertDiagnosed(.avoidInitializerStyleCast("UInt8(257)"))
23+
XCTAssertDiagnosed(.avoidInitializerStyleCast("Int16(54)"))
24+
XCTAssertDiagnosed(.avoidInitializerStyleCast("Int32(54)"))
25+
XCTAssertDiagnosed(.avoidInitializerStyleCast("Int64(54)"))
26+
XCTAssertDiagnosed(.avoidInitializerStyleCast("Character(\"s\")"))
27+
XCTAssertDiagnosed(.avoidInitializerStyleCast("Int(2) "))
28+
XCTAssertNotDiagnosed(.avoidInitializerStyleCast("Int(bitPattern: 123456)"))
3029
}
3130

3231
#if !os(macOS)

0 commit comments

Comments
 (0)