Skip to content

Commit

Permalink
Ugh
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulTaykalo committed Mar 10, 2022
1 parent ad04577 commit 19b2b76
Showing 1 changed file with 51 additions and 27 deletions.
78 changes: 51 additions & 27 deletions Source/SwiftLintFramework/Rules/Idiomatic/SyntacticSugarRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public struct SyntacticSugarRule: SubstitutionCorrectableRule, ConfigurationProv
let negativeLookBehind = "(?:(?<!\\.))"
return negativeLookBehind + "\\b(" + types.joined(separator: "|") + ")\\s*"
// Open generic
+ "<"
+ "(<\\s*)"

// Everything but new generic
+ "[^<]*?"
Expand All @@ -21,8 +21,14 @@ public struct SyntacticSugarRule: SubstitutionCorrectableRule, ConfigurationProv
// Everything but new generic
+ "[^<]*?"

// 2nd Optional inner generic (as value type in dictionary)
+ "(?:<[^<]*?>)?"

// Everything but new generic
+ "[^<]*?"

// Closed generic
+ ">"
+ "(\\s*>)"
}

public init() {}
Expand Down Expand Up @@ -68,7 +74,7 @@ public struct SyntacticSugarRule: SubstitutionCorrectableRule, ConfigurationProv
],
corrections: [
Example("let x: Array<String>"): Example("let x: [String]"),
Example("let x: Array< String >"): Example("let x: [ String ]"),
Example("let x: Array< String >"): Example("let x: [String]"),
Example("let x: Dictionary<Int, String>"): Example("let x: [Int: String]"),
Example("let x: Dictionary<Int , String>"): Example("let x: [Int : String]"),
Example("let x: Optional<Int>"): Example("let x: Int?"),
Expand All @@ -81,7 +87,15 @@ public struct SyntacticSugarRule: SubstitutionCorrectableRule, ConfigurationProv
Example("let x = Array<String>.array(of: object)"): Example("let x = [String].array(of: object)"),
Example("let x: Swift.Optional<String>"): Example("let x: String?"),
Example("let x:Dictionary<String, Dictionary<Int, Int>>"): Example("let x:[String: [Int: Int]]"),
Example("let x:Dictionary<Dictionary<Int, Int>, String>"): Example("let x:[[Int: Int]: String]")
Example("let x:Dictionary<Dictionary<Int, Int>, String>"): Example("let x:[[Int: Int]: String]"),
Example("""
enum Box<T> {}
let x:Dictionary<Box<String>, Box<Bool>>
"""):
Example("""
enum Box<T> {}
let x:[Box<String>: Box<Bool>]
""")
]
)

Expand Down Expand Up @@ -110,46 +124,56 @@ public struct SyntacticSugarRule: SubstitutionCorrectableRule, ConfigurationProv
private func substitute(_ declaration: String) -> String {
let originalRange = NSRange(location: 0, length: declaration.count)
guard
let typeRange = regex(pattern).firstMatch(in: declaration, options: [], range: originalRange)?.range(at: 1)
let match = regex(pattern).firstMatch(in: declaration, options: [], range: originalRange)
else {
return declaration
}

let typeRange = match.range(at: 1)
let openBracketRange = match.range(at: 2)
let closedBracketRange = match.range(at: 3)

// replace found type
let substitutionResult: String
let nsDeclaration = declaration.bridge()
let containerType = nsDeclaration.substring(with: typeRange)
let innerString = nsDeclaration.substring(from: typeRange.upperBound)
let prefix = nsDeclaration.substring(to: typeRange.lowerBound)

let recusiveUpdatedInnerTypes = prefix + containerType + substitute(innerString)

let containerType = declaration.bridge().substring(with: typeRange)
let prefix = declaration.bridge().substring(to: typeRange.lowerBound)
switch containerType {
case "Optional", "Swift.Optional":
let genericType = recusiveUpdatedInnerTypes.bridge().substring(from: typeRange.upperBound)
.replacingOccurrences(of: " ", with: "")
.replacingOccurrences(of: "<", with: "")
.replacingOccurrences(of: ">", with: "")
let genericType = declaration.bridge()
.replacingCharacters(in: closedBracketRange, with: "").bridge()
.replacingCharacters(in: openBracketRange, with: "")
.substring(from: typeRange.upperBound)
substitutionResult = "\(prefix)\(genericType)?"

case "ImplicitlyUnwrappedOptional", "Swift.ImplicitlyUnwrappedOptional":
let genericType = recusiveUpdatedInnerTypes.bridge().substring(from: typeRange.upperBound)
.replacingOccurrences(of: " ", with: "")
.replacingOccurrences(of: "<", with: "")
.replacingOccurrences(of: ">", with: "")
let genericType = declaration.bridge()
.replacingCharacters(in: closedBracketRange, with: "").bridge()
.replacingCharacters(in: openBracketRange, with: "")
.substring(from: typeRange.upperBound)

substitutionResult = "\(prefix)\(genericType)!"
case "Array", "Swift.Array":
substitutionResult = prefix + recusiveUpdatedInnerTypes.bridge().substring(from: typeRange.upperBound)
.replacingOccurrences(of: "<", with: "[")
.replacingOccurrences(of: ">", with: "]")
let genericType = declaration.bridge()
.replacingCharacters(in: closedBracketRange, with: "]").bridge()
.replacingCharacters(in: openBracketRange, with: "[")
.substring(from: typeRange.upperBound)

substitutionResult = "\(prefix)\(genericType)"
case "Dictionary", "Swift.Dictionary":
substitutionResult = prefix + recusiveUpdatedInnerTypes.bridge().substring(from: typeRange.upperBound)
.replacingOccurrences(of: "<", with: "[")
.replacingOccurrences(of: ">", with: "]")
let genericType = declaration.bridge()
.replacingCharacters(in: closedBracketRange, with: "]").bridge()
.replacingCharacters(in: openBracketRange, with: "[")
.replacingOccurrences(of: ",", with: ":")
.substring(from: typeRange.upperBound)

substitutionResult = "\(prefix)\(genericType)"
default:
substitutionResult = declaration
}

return substitutionResult
let finalResult = substitute(substitutionResult)
return finalResult

}

private func violationResults(in file: SwiftLintFile) -> [NSTextCheckingResult] {
Expand Down

0 comments on commit 19b2b76

Please sign in to comment.