Update for 0.47.0 release

This commit is contained in:
Nick Lockwood
2020-10-15 00:40:51 +01:00
parent f319b918f0
commit 1f96916df2
50 changed files with 564 additions and 584 deletions
+12
View File
@@ -1,5 +1,17 @@
# Change Log
## [0.47.0](https://github.com/nicklockwood/SwiftFormat/releases/tag/0.47.0) (2020-10-14)
- Indenting of wrapped `if`, `guard`, `while`, etc. now matches Xcode 12 behavior
- Added `--assetliterals` option for managing how image/color literal length is handled
- Added `enumNamespaces` rule to replace classes/structs that only have static members with an enum
- Added `extensionAccessControl` rule to hoist/unhoist access control modifiers inside extensions
- Added `markTypes` rule for automatically inserting `MARK:` comments between type declarations
- Added `sortedSwitchCases` rule to automatically sort grouped switch cases alphabetically
- Added ``--wrapreturntype` option to control how return type is wrapped in function declarations
- The `organizeDeclarations` rule is now also applied to extensions
- Updated `--xcodeindentation` behavior for Xcode 12
## [0.46.3](https://github.com/nicklockwood/SwiftFormat/releases/tag/0.46.3) (2020-09-20)
- Fixed bug where `redundantType` rule corrupted assignments involving ternary expressions
Binary file not shown.
@@ -68,7 +68,7 @@ class FreeTextTableCellView: NSTableCellView {
extension FreeTextTableCellView: NSTextFieldDelegate {
override func controlTextDidChange(_ obj: Notification) {
guard let textView: NSTextView = obj.userInfo!["NSFieldEditor"] as? NSTextView,
let freeText = objectValue as? UserSelectionFreeText
let freeText = objectValue as? UserSelectionFreeText
else {
return
}
+4 -4
View File
@@ -40,8 +40,8 @@ struct SavedOption {
}
}
extension SavedOption {
fileprivate init(_ rep: OptionsStore.OptionRepresentation) throws {
private extension SavedOption {
init(_ rep: OptionsStore.OptionRepresentation) throws {
guard let descriptor = Descriptors.byName[rep.id] else {
throw FormatError.options("Unknown option \(rep.id)")
}
@@ -53,8 +53,8 @@ extension SavedOption {
}
}
extension FormatOptions {
fileprivate init(_ rep: OptionsStore.OptionStoreRepresentation) throws {
private extension FormatOptions {
init(_ rep: OptionsStore.OptionStoreRepresentation) throws {
var formatOptions = FormatOptions.default
for descriptor in Descriptors.all.reversed() {
// By loading formatting options in reverse, we ensure that
+2 -2
View File
@@ -60,8 +60,8 @@ extension Rule: Comparable {
}
}
extension Rule {
fileprivate init(_ ruleRep: (String, Bool)) {
private extension Rule {
init(_ ruleRep: (String, Bool)) {
self.init(name: ruleRep.0, isEnabled: ruleRep.1)
}
}
@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>19G2021</string>
<string>19H2</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDocumentTypes</key>
@@ -36,7 +36,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.46.3</string>
<string>0.47.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
@@ -62,7 +62,7 @@
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key>
<string>10.11</string>
<string>10.14</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2016 Nick Lockwood. All rights reserved.</string>
<key>NSMainStoryboardFile</key>
@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>19G2021</string>
<string>19H2</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
@@ -41,7 +41,7 @@
<key>DTXcodeBuild</key>
<string>12A7209</string>
<key>LSMinimumSystemVersion</key>
<string>10.11</string>
<string>10.14</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
@@ -6,35 +6,35 @@
<dict>
<key>Resources/AppIcon.icns</key>
<data>
IsifGQ6u46Cp81IAOcJIcLkuxGw=
49ta0JaEQzFhN907kv6SiH1kchU=
</data>
<key>Resources/Assets.car</key>
<data>
DQYLd/jkRuxSrE6Ok/kK1WIbH3c=
YiheLpyp+SRLXxFU721UYx8oI6c=
</data>
<key>Resources/Base.lproj/Main.storyboardc/9ZR-Qg-hHT-view-iDF-FY-6tf.nib</key>
<data>
PJwNXgb4aiLkgOZKY5pNFVMSGPI=
NgkuD0ekbF0F8PCXGo2XyDdQEZ4=
</data>
<key>Resources/Base.lproj/Main.storyboardc/Info.plist</key>
<data>
BMnGqn+yx3vG3HhgYj1L+IMJwXE=
+/DJ7okKXSwZ02uqruRsLmLrVME=
</data>
<key>Resources/Base.lproj/Main.storyboardc/MainMenu.nib</key>
<data>
0z5SQhAJml+mZe/49kSf+ItZEEw=
lI7KbQws4PaWE18pL0llqYlccT0=
</data>
<key>Resources/Base.lproj/Main.storyboardc/MainWindowTabViewController.nib</key>
<data>
yUeufolLhKGDGDqfc5SVyDRHM2s=
sWeCbAsRLvNYKtIy6w6ivu/7Qpk=
</data>
<key>Resources/Base.lproj/Main.storyboardc/NSWindowController-B8D-0N-5wS.nib</key>
<data>
LIEBJbRA6qayOSDiWRqj5U0u4gI=
Zdo9GV43c2YGAWk8LB9vj4kOsAg=
</data>
<key>Resources/Base.lproj/Main.storyboardc/RulesViewController.nib</key>
<data>
rfAECe1mswYnskltpW21hKH6NEU=
beYTI7gNKts02jpMY7lcElpKxsk=
</data>
<key>Resources/Base.lproj/Main.storyboardc/XfG-lQ-9wD-view-m2S-Jp-Qdl.nib</key>
<data>
@@ -182,105 +182,69 @@
<dict>
<key>cdhash</key>
<data>
kToM7834srzzv6TNZRRMlyNBEJY=
Z+z+6QsyriEW62UtZKRx4w/hNm8=
</data>
<key>requirement</key>
<string>anchor apple generic and identifier "com.charcoaldesign.SwiftFormat-for-Xcode.SourceEditorExtension" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "8VQKF583ED")</string>
</dict>
<key>Resources/AppIcon.icns</key>
<dict>
<key>hash</key>
<data>
IsifGQ6u46Cp81IAOcJIcLkuxGw=
</data>
<key>hash2</key>
<data>
HhzZtyg6k6342A4NxIR25LPdwke/QvBhXVxaZPTv/yo=
uL7GZda4f/Vm3xjeFMdkmr5AHvnjhcJFkLlXkF6xsf4=
</data>
</dict>
<key>Resources/Assets.car</key>
<dict>
<key>hash</key>
<data>
DQYLd/jkRuxSrE6Ok/kK1WIbH3c=
</data>
<key>hash2</key>
<data>
FhMDp6Rp6kAYwyARB6RKT01iGzwDEcGs5vR1R9duSdI=
GYXZ11g7/0ggejEJ1zVPKm8+O+vtpstht2WvFXURoag=
</data>
</dict>
<key>Resources/Base.lproj/Main.storyboardc/9ZR-Qg-hHT-view-iDF-FY-6tf.nib</key>
<dict>
<key>hash</key>
<data>
PJwNXgb4aiLkgOZKY5pNFVMSGPI=
</data>
<key>hash2</key>
<data>
RyofvGzD02vsmP570BUBJf3H2iKlskFLkNM2Yqiz5iE=
SFlU7n9v5kte+wKrebcdyk34TT5YjcOgi20SozeVsAE=
</data>
</dict>
<key>Resources/Base.lproj/Main.storyboardc/Info.plist</key>
<dict>
<key>hash</key>
<data>
BMnGqn+yx3vG3HhgYj1L+IMJwXE=
</data>
<key>hash2</key>
<data>
mfZctbb5otaIASUXlSGMkw6F/3XSJvLj7h838758854=
or34ef1CtY0IAqy8rCQrmLYSv5sn6jdShMx4sLw+9s4=
</data>
</dict>
<key>Resources/Base.lproj/Main.storyboardc/MainMenu.nib</key>
<dict>
<key>hash</key>
<data>
0z5SQhAJml+mZe/49kSf+ItZEEw=
</data>
<key>hash2</key>
<data>
I0QWL2U6Mi/KJrb8xHWabsuuba7PjN4HXmlXIgFZdIU=
qrLtyVyZiN2qpsNs1XdrvF9DrmXStoXqUyrcRkYL+WQ=
</data>
</dict>
<key>Resources/Base.lproj/Main.storyboardc/MainWindowTabViewController.nib</key>
<dict>
<key>hash</key>
<data>
yUeufolLhKGDGDqfc5SVyDRHM2s=
</data>
<key>hash2</key>
<data>
O5MH3wMtEvTuxPNzVokAZkPqJ622y8tIqvKzGQFwBvM=
0niOKWSTJYKDJD/YK454D67ykqdcOV63t7geVMDXWcg=
</data>
</dict>
<key>Resources/Base.lproj/Main.storyboardc/NSWindowController-B8D-0N-5wS.nib</key>
<dict>
<key>hash</key>
<data>
LIEBJbRA6qayOSDiWRqj5U0u4gI=
</data>
<key>hash2</key>
<data>
69SnBbVIaXKwhMt6LtIIXP6vk0ZxA4x9hx3kTVT9RYU=
22rpMYPNyrK/2QRHNpkFjy8pphfvIWoc+SmS6USZBB4=
</data>
</dict>
<key>Resources/Base.lproj/Main.storyboardc/RulesViewController.nib</key>
<dict>
<key>hash</key>
<data>
rfAECe1mswYnskltpW21hKH6NEU=
</data>
<key>hash2</key>
<data>
4qql7sNGICUVfrzSrHX9eiNz8k8XkuAPGmpLI2LN2Ck=
LsMenOnAUxX3uVz8bsmLY81eVMjvyPE5PJrkBheicG0=
</data>
</dict>
<key>Resources/Base.lproj/Main.storyboardc/XfG-lQ-9wD-view-m2S-Jp-Qdl.nib</key>
<dict>
<key>hash</key>
<data>
9QDdTtGXlGK6L/lwYL92eAU0kMk=
</data>
<key>hash2</key>
<data>
8/fmpfJkFkrcEOjAXPJGkiexY7vP8bksKSro2h6+1O0=
+8 -8
View File
@@ -131,11 +131,11 @@ func preprocessArguments(_ args: [String], _ names: [String]) throws -> [String:
arg = String(arg.dropLast())
}
if let existing = namedArgs[name], !existing.isEmpty,
// TODO: find a more general way to represent merge-able options
["exclude", "unexclude", "disable", "enable", "rules"].contains(name) ||
Descriptors.all.contains(where: {
$0.argumentName == name && $0.isSetType
})
// TODO: find a more general way to represent merge-able options
["exclude", "unexclude", "disable", "enable", "rules"].contains(name) ||
Descriptors.all.contains(where: {
$0.argumentName == name && $0.isSetType
})
{
namedArgs[name] = existing + "," + arg
} else {
@@ -250,14 +250,14 @@ func mergeArguments(_ args: [String: String], into config: [String: String]) thr
var output = args
// Merge excluded urls
if let exclude = output["exclude"].map(parseCommaDelimitedList),
var excluded = input["exclude"].map({ Set(parseCommaDelimitedList($0)) })
var excluded = input["exclude"].map({ Set(parseCommaDelimitedList($0)) })
{
excluded.formUnion(exclude)
output["exclude"] = Array(excluded).sorted().joined(separator: ",")
}
// Merge unexcluded urls
if let unexclude = output["unexclude"].map(parseCommaDelimitedList),
var unexcluded = input["unexclude"].map({ Set(parseCommaDelimitedList($0)) })
var unexcluded = input["unexclude"].map({ Set(parseCommaDelimitedList($0)) })
{
unexcluded.formUnion(unexclude)
output["unexclude"] = Array(unexcluded).sorted().joined(separator: ",")
@@ -443,7 +443,7 @@ func argumentsFor(_ options: Options, excludingDefaults: Bool = false) -> [Strin
// Special case for swiftVersion
// TODO: find a better solution for this
if descriptor.argumentName == Descriptors.swiftVersion.argumentName,
value == Version.undefined.rawValue
value == Version.undefined.rawValue
{
continue
}
+3 -3
View File
@@ -485,8 +485,8 @@ func processArguments(_ args: [String], in directory: String) -> ExitCode {
$0.trimmingCharacters(in: .whitespacesAndNewlines)
}
guard (1 ... 2).contains(parts.count),
let start = parts.first.flatMap(Int.init),
let end = parts.last.flatMap(Int.init)
let start = parts.first.flatMap(Int.init),
let end = parts.last.flatMap(Int.init)
else {
throw FormatError.options("Unsupported --linerange value '\(arg)'")
}
@@ -1013,7 +1013,7 @@ func processInput(_ inputURLs: [URL],
}
// Save cache
if outputFlags.filesChecked > 0, let cache = cache, let cacheURL = cacheURL,
let cacheDirectory = cacheDirectory
let cacheDirectory = cacheDirectory
{
do {
let data = try JSONEncoder().encode(cache)
+1 -1
View File
@@ -2,7 +2,7 @@
// Formatter.swift
// SwiftFormat
//
// Version 0.46.3
// Version 0.47.0
//
// Created by Nick Lockwood on 12/08/2016.
// Copyright 2016 Nick Lockwood
+39 -39
View File
@@ -86,13 +86,13 @@ extension Formatter {
break
case .ifMultiline:
guard let openBracket = index(of: .startOfScope("{"), after: endOfFunctionScope),
let returnArrowIndex = index(of: .operator("->", .infix), after: endOfFunctionScope),
returnArrowIndex < openBracket
let returnArrowIndex = index(of: .operator("->", .infix), after: endOfFunctionScope),
returnArrowIndex < openBracket
else { return }
// If the return arrow isnt on its own line, wrap it
if let previousNonSpaceOrComment = index(of: .nonSpaceOrComment, before: returnArrowIndex),
startOfLine(at: returnArrowIndex) < previousNonSpaceOrComment
startOfLine(at: returnArrowIndex) < previousNonSpaceOrComment
{
insertSpace(indentForLine(at: returnArrowIndex), at: returnArrowIndex)
insertLinebreak(at: returnArrowIndex)
@@ -136,7 +136,7 @@ extension Formatter {
index += 1
}
while let commaIndex = self.lastIndex(of: .delimiter(","), in: i + 1 ..< index),
var linebreakIndex = self.index(of: .nonSpaceOrComment, after: commaIndex)
var linebreakIndex = self.index(of: .nonSpaceOrComment, after: commaIndex)
{
if let index = self.index(of: .nonSpace, before: linebreakIndex) {
linebreakIndex = index + 1
@@ -193,7 +193,7 @@ extension Formatter {
var lastBreakIndex: Int?
var index = firstArgumentIndex
while let commaIndex = self.index(of: .delimiter(","), in: index ..< endOfScope),
var linebreakIndex = self.index(of: .nonSpaceOrComment, after: commaIndex)
var linebreakIndex = self.index(of: .nonSpaceOrComment, after: commaIndex)
{
if let index = self.index(of: .nonSpace, before: linebreakIndex) {
linebreakIndex = index + 1
@@ -253,8 +253,8 @@ extension Formatter {
case "(":
/// Don't wrap color/image literals due to Xcode bug
guard let prevToken = self.token(at: i - 1),
prevToken != .keyword("#colorLiteral"),
prevToken != .keyword("#imageLiteral")
prevToken != .keyword("#colorLiteral"),
prevToken != .keyword("#imageLiteral")
else {
return
}
@@ -294,7 +294,7 @@ extension Formatter {
}
if completePartialWrapping,
let firstLinebreakIndex = index(of: .linebreak, in: i + 1 ..< endOfScope)
let firstLinebreakIndex = index(of: .linebreak, in: i + 1 ..< endOfScope)
{
switch mode {
case .beforeFirst:
@@ -375,8 +375,8 @@ extension Formatter {
if currentRule == FormatRules.wrap {
let nextWrapIndex = indexOfNextWrap() ?? endOfLine(at: i)
if nextWrapIndex > lastIndex,
maxWidth < lineLength(from: max(lastIndex, 0), upTo: nextWrapIndex),
!willWrapAtStartOfReturnType(maxWidth: maxWidth)
maxWidth < lineLength(from: max(lastIndex, 0), upTo: nextWrapIndex),
!willWrapAtStartOfReturnType(maxWidth: maxWidth)
{
wrapArgumentsWithoutPartialWrapping()
lastIndex = nextWrapIndex
@@ -413,13 +413,13 @@ extension Formatter {
}
if token(at: index - 1)?.isSpace == true,
token(at: index + 1)?.isSpace == true
token(at: index + 1)?.isSpace == true
{
// Need to remove one
removeToken(at: index + 1)
} else if case .startOfScope = tokens[index] {
if tokenOutsideParenRequiresSpacing(at: index - 1),
tokenInsideParenRequiresSpacing(at: index + 1)
tokenInsideParenRequiresSpacing(at: index + 1)
{
// Need to insert one
insert(.space(" "), at: index + 1)
@@ -705,8 +705,8 @@ extension Formatter {
// immediately follows the `func` keyword:
// https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#grammar_function-name
if keyword == "func",
let methodName = parser.next(.nonSpaceOrCommentOrLinebreak, after: keywordIndex),
options.lifecycleMethods.contains(methodName.string)
let methodName = parser.next(.nonSpaceOrCommentOrLinebreak, after: keywordIndex),
options.lifecycleMethods.contains(methodName.string)
{
return .lifecycle
}
@@ -744,7 +744,7 @@ extension Formatter {
while searchIndex < keywordIndex {
if let visibility = Visibility(rawValue: parser.tokens[searchIndex].string),
parser.next(.nonSpaceOrComment, after: searchIndex) != .startOfScope("(")
parser.next(.nonSpaceOrComment, after: searchIndex) != .startOfScope("(")
{
return visibility
}
@@ -794,10 +794,10 @@ extension Formatter {
// If there is a code block at the end of the declaration that is _not_ a closure,
// then this declaration has a body.
if let lastClosingBraceIndex = declarationParser.index(of: .endOfScope("}"), before: declarationParser.tokens.count),
let lastOpeningBraceIndex = declarationParser.index(of: .startOfScope("{"), before: lastClosingBraceIndex),
declarationTypeTokenIndex < lastOpeningBraceIndex,
declarationTypeTokenIndex < lastClosingBraceIndex,
!declarationParser.isStartOfClosure(at: lastOpeningBraceIndex)
let lastOpeningBraceIndex = declarationParser.index(of: .startOfScope("{"), before: lastClosingBraceIndex),
declarationTypeTokenIndex < lastOpeningBraceIndex,
declarationTypeTokenIndex < lastClosingBraceIndex,
!declarationParser.isStartOfClosure(at: lastOpeningBraceIndex)
{
hasBody = true
} else {
@@ -856,8 +856,8 @@ extension Formatter {
var searchIndex = parser.tokens.count - 1
while searchIndex > 0,
let token = parser.token(at: searchIndex),
token.isSpaceOrCommentOrLinebreak
let token = parser.token(at: searchIndex),
token.isSpaceOrCommentOrLinebreak
{
if token.isLinebreak {
numberOfTrailingLinebreaks += 1
@@ -914,7 +914,7 @@ extension Formatter {
let potentialSeparatorRange = commentStartIndex ..< (commentStartIndex + potentialCategorySeparator.count)
guard parser.tokens.indices.contains(potentialSeparatorRange.upperBound),
let nextNonwhitespaceIndex = parser.index(of: .nonSpaceOrLinebreak, after: potentialSeparatorRange.upperBound)
let nextNonwhitespaceIndex = parser.index(of: .nonSpaceOrLinebreak, after: potentialSeparatorRange.upperBound)
else { continue }
// Check the edit distance of this existing comment with the potential
@@ -1025,22 +1025,22 @@ extension Formatter {
// Sort primarily by category
if sortByCategory,
let lhsCategorySortOrder = Formatter.categoryOrdering.index(of: lhs.category),
let rhsCategorySortOrder = Formatter.categoryOrdering.index(of: rhs.category),
lhsCategorySortOrder != rhsCategorySortOrder
let lhsCategorySortOrder = Formatter.categoryOrdering.index(of: lhs.category),
let rhsCategorySortOrder = Formatter.categoryOrdering.index(of: rhs.category),
lhsCategorySortOrder != rhsCategorySortOrder
{
return lhsCategorySortOrder < rhsCategorySortOrder
}
// Within individual categories (excluding .beforeMarks), sort by the declaration type
if sortByType,
lhs.category != .beforeMarks,
rhs.category != .beforeMarks,
let lhsType = lhs.type,
let rhsType = rhs.type,
let lhsTypeSortOrder = Formatter.categorySubordering.index(of: lhsType),
let rhsTypeSortOrder = Formatter.categorySubordering.index(of: rhsType),
lhsTypeSortOrder != rhsTypeSortOrder
lhs.category != .beforeMarks,
rhs.category != .beforeMarks,
let lhsType = lhs.type,
let rhsType = rhs.type,
let lhsTypeSortOrder = Formatter.categorySubordering.index(of: lhsType),
let rhsTypeSortOrder = Formatter.categorySubordering.index(of: rhsType),
lhsTypeSortOrder != rhsTypeSortOrder
{
return lhsTypeSortOrder < rhsTypeSortOrder
}
@@ -1058,7 +1058,7 @@ extension Formatter {
// declarations that don't have an `init` declaration.
// We have to take care to not reorder any properties (but reordering functions etc is ok!)
if typeDeclaration.kind == "struct",
!typeDeclaration.body.contains(where: { $0.keyword == "init" })
!typeDeclaration.body.contains(where: { $0.keyword == "init" })
{
/// Whether or not this declaration is an instance property that can affect
/// the parameters struct's synthesized memberwise initializer
@@ -1083,8 +1083,8 @@ extension Formatter {
var hasWillSetOrDidSetBlock = false
if let bodyOpenBrace = parser.index(of: .startOfScope("{"), after: -1),
let firstBodyToken = parser.next(.nonSpaceOrCommentOrLinebreak, after: bodyOpenBrace),
firstBodyToken.string == "willSet" || firstBodyToken.string == "didSet"
let firstBodyToken = parser.next(.nonSpaceOrCommentOrLinebreak, after: bodyOpenBrace),
firstBodyToken.string == "willSet" || firstBodyToken.string == "didSet"
{
hasWillSetOrDidSetBlock = true
}
@@ -1139,7 +1139,7 @@ extension Formatter {
// Build the MARK declaration, but only when there is more than one category present.
if numberOfCategories > 1,
let markComment = category.markComment(from: options.categoryMarkComment)
let markComment = category.markComment(from: options.categoryMarkComment)
{
let firstDeclaration = sortedDeclarations[indexOfFirstDeclaration].declaration
let declarationParser = Formatter(firstDeclaration.tokens)
@@ -1220,14 +1220,14 @@ extension Formatter {
// If there are any annotations, skip past them
while startOfModifiers < indexOfKeyword,
openTokensFormatter.tokens[startOfModifiers].string.hasPrefix("@")
|| openTokensFormatter.tokens[startOfModifiers].isSpaceOrCommentOrLinebreak
openTokensFormatter.tokens[startOfModifiers].string.hasPrefix("@")
|| openTokensFormatter.tokens[startOfModifiers].isSpaceOrCommentOrLinebreak
{
startOfModifiers += 1
// Also skip through annotation bodies, like in `@available(iOS 14.0, *)`
if openTokensFormatter.tokens[startOfModifiers] == .startOfScope("("),
let endOfScope = openTokensFormatter.endOfScope(at: startOfModifiers)
let endOfScope = openTokensFormatter.endOfScope(at: startOfModifiers)
{
startOfModifiers = endOfScope + 1
}
+54 -54
View File
@@ -143,8 +143,8 @@ private struct Inference {
var spaced = [String: Int](), unspaced = [String: Int]()
formatter.forEach(.operator) { i, token in
guard case let .operator(name, .infix) = token, name != ".",
let nextToken = formatter.next(.nonSpaceOrCommentOrLinebreak, after: i),
nextToken.string != ")", nextToken.string != ","
let nextToken = formatter.next(.nonSpaceOrCommentOrLinebreak, after: i),
nextToken.string != ")", nextToken.string != ","
else {
return
}
@@ -166,8 +166,8 @@ private struct Inference {
]
for pair in relatedPairs {
if noSpaceOperators.contains(pair.0),
!noSpaceOperators.contains(pair.1),
!operators.contains(pair.1)
!noSpaceOperators.contains(pair.1),
!operators.contains(pair.1)
{
noSpaceOperators.insert(pair.1)
} else if noSpaceOperators.contains(pair.1),
@@ -184,7 +184,7 @@ private struct Inference {
var voids = 0, tuples = 0
formatter.forEach(.identifier("Void")) { i, _ in
if let prevToken = formatter.last(.nonSpaceOrCommentOrLinebreak, before: i),
[.operator(".", .prefix), .operator(".", .infix), .keyword("typealias")].contains(prevToken)
[.operator(".", .prefix), .operator(".", .infix), .keyword("typealias")].contains(prevToken)
{
return
}
@@ -192,10 +192,10 @@ private struct Inference {
}
formatter.forEach(.startOfScope("(")) { i, _ in
if let prevIndex = formatter.index(of: .nonSpaceOrCommentOrLinebreak, before: i),
let prevToken = formatter.token(at: prevIndex), prevToken == .operator("->", .infix),
let nextIndex = formatter.index(of: .nonSpaceOrLinebreak, after: i),
let nextToken = formatter.token(at: nextIndex), nextToken.string == ")",
formatter.next(.nonSpaceOrCommentOrLinebreak, after: nextIndex) != .operator("->", .infix)
let prevToken = formatter.token(at: prevIndex), prevToken == .operator("->", .infix),
let nextIndex = formatter.index(of: .nonSpaceOrLinebreak, after: i),
let nextToken = formatter.token(at: nextIndex), nextToken.string == ")",
formatter.next(.nonSpaceOrCommentOrLinebreak, after: nextIndex) != .operator("->", .infix)
{
tuples += 1
}
@@ -207,9 +207,9 @@ private struct Inference {
var trailing = 0, noTrailing = 0
formatter.forEach(.endOfScope("]")) { i, token in
guard let linebreakIndex = formatter.index(of: .nonSpaceOrComment, before: i),
case .linebreak = formatter.tokens[linebreakIndex],
let prevTokenIndex = formatter.index(of: .nonSpaceOrCommentOrLinebreak, before: linebreakIndex + 1),
let token = formatter.token(at: prevTokenIndex)
case .linebreak = formatter.tokens[linebreakIndex],
let prevTokenIndex = formatter.index(of: .nonSpaceOrCommentOrLinebreak, before: linebreakIndex + 1),
let token = formatter.token(at: prevTokenIndex)
else {
return
}
@@ -261,13 +261,13 @@ private struct Inference {
formatter.forEach(.startOfScope("{")) { i, _ in
// Check this isn't an inline block
guard let closingBraceIndex = formatter.index(of: .endOfScope("}"), after: i),
formatter.index(of: .linebreak, in: i + 1 ..< closingBraceIndex) != nil
formatter.index(of: .linebreak, in: i + 1 ..< closingBraceIndex) != nil
else {
return
}
// Check if brace is wrapped
if let prevTokenIndex = formatter.index(of: .nonSpace, before: i),
let prevToken = formatter.token(at: prevTokenIndex)
let prevToken = formatter.token(at: prevTokenIndex)
{
switch prevToken {
case .identifier, .keyword, .endOfScope, .operator("?", .postfix), .operator("!", .postfix):
@@ -286,11 +286,11 @@ private struct Inference {
var indented = 0, notIndented = 0, outdented = 0
formatter.forEach(.startOfScope("#if")) { i, _ in
if let indent = formatter.token(at: i - 1), case let .space(string) = indent,
!string.isEmpty
!string.isEmpty
{
// Indented, check next line
if let nextLineIndex = formatter.index(of: .linebreak, after: i),
let nextIndex = formatter.index(of: .nonSpaceOrLinebreak, after: nextLineIndex)
let nextIndex = formatter.index(of: .nonSpaceOrLinebreak, after: nextLineIndex)
{
switch formatter.tokens[nextIndex - 1] {
case let .space(innerString):
@@ -316,7 +316,7 @@ private struct Inference {
}
// Not indented, check next line
if let nextLineIndex = formatter.index(of: .linebreak, after: i),
let nextIndex = formatter.index(of: .nonSpaceOrLinebreak, after: nextLineIndex)
let nextIndex = formatter.index(of: .nonSpaceOrLinebreak, after: nextLineIndex)
{
switch formatter.tokens[nextIndex - 1] {
case let .space(string):
@@ -363,8 +363,8 @@ private struct Inference {
var balanced = 0, sameLine = 0
formatter.forEach(.startOfScope("(")) { i, _ in
guard let closingBraceIndex = formatter.endOfScope(at: i),
let linebreakIndex = formatter.index(of: .linebreak, after: i),
formatter.index(of: .nonSpaceOrComment, after: i) == linebreakIndex
let linebreakIndex = formatter.index(of: .linebreak, after: i),
formatter.index(of: .nonSpaceOrComment, after: i) == linebreakIndex
else {
return
}
@@ -490,7 +490,7 @@ private struct Inference {
switch prevToken {
case .keyword("let"), .keyword("var"):
guard let prevPrevToken = formatter.last(.nonSpaceOrCommentOrLinebreak, before: prevIndex),
[.keyword("case"), .endOfScope("case"), .delimiter(",")].contains(prevPrevToken)
[.keyword("case"), .endOfScope("case"), .delimiter(",")].contains(prevPrevToken)
else {
// Tuple assignment, not a pattern
return
@@ -516,9 +516,9 @@ private struct Inference {
for i in range {
let token = formatter.tokens[i]
if case .identifier = token, let index = argNames.index(of: token.unescaped()),
formatter.last(.nonSpaceOrCommentOrLinebreak, before: i)?.isOperator(".") == false,
formatter.next(.nonSpaceOrCommentOrLinebreak, after: i) != .delimiter(":") ||
formatter.currentScope(at: i) == .startOfScope("[")
formatter.last(.nonSpaceOrCommentOrLinebreak, before: i)?.isOperator(".") == false,
formatter.next(.nonSpaceOrCommentOrLinebreak, after: i) != .delimiter(":") ||
formatter.currentScope(at: i) == .startOfScope("[")
{
argNames.remove(at: index)
associatedData.remove(at: index)
@@ -531,8 +531,8 @@ private struct Inference {
// Function arguments
formatter.forEachToken { i, token in
guard case let .keyword(keyword) = token, ["func", "init", "subscript"].contains(keyword),
let startIndex = formatter.index(of: .startOfScope("("), after: i),
let endIndex = formatter.index(of: .endOfScope(")"), after: startIndex) else { return }
let startIndex = formatter.index(of: .startOfScope("("), after: i),
let endIndex = formatter.index(of: .endOfScope(")"), after: startIndex) else { return }
let isOperator = (keyword == "subscript") ||
(keyword == "func" && formatter.next(.nonSpaceOrCommentOrLinebreak, after: i)?.isOperator == true)
var index = startIndex
@@ -658,13 +658,13 @@ private struct Inference {
continue
case .keyword("switch"):
guard let nextIndex = formatter.index(of: .startOfScope("{"), after: i),
var endIndex = formatter.index(of: .endOfScope, after: nextIndex)
var endIndex = formatter.index(of: .endOfScope, after: nextIndex)
else {
return // error
}
while formatter.tokens[endIndex] != .endOfScope("}") {
guard let nextIndex = formatter.index(of: .startOfScope(":"), after: endIndex),
let _endIndex = formatter.index(of: .endOfScope, after: nextIndex)
let _endIndex = formatter.index(of: .endOfScope, after: nextIndex)
else {
return // error
}
@@ -756,9 +756,9 @@ private struct Inference {
}
case .keyword("extension"), .keyword("struct"), .keyword("enum"):
guard formatter.last(.nonSpaceOrCommentOrLinebreak, before: index) != .keyword("import"),
let scopeStart = formatter.index(of: .startOfScope("{"), after: index) else { return }
let scopeStart = formatter.index(of: .startOfScope("{"), after: index) else { return }
guard let nameToken = formatter.next(.identifier, after: index),
case let .identifier(name) = nameToken
case let .identifier(name) = nameToken
else {
return // error
}
@@ -811,9 +811,9 @@ private struct Inference {
lastKeyword = ""
var localNames = localNames
guard let keywordIndex = formatter.index(of: .keyword, before: index),
let prevKeywordIndex = formatter.index(of: .keyword, before: keywordIndex),
let prevKeywordToken = formatter.token(at: prevKeywordIndex),
case .keyword("for") = prevKeywordToken else { return }
let prevKeywordIndex = formatter.index(of: .keyword, before: keywordIndex),
let prevKeywordToken = formatter.token(at: prevKeywordIndex),
case .keyword("for") = prevKeywordToken else { return }
for token in formatter.tokens[prevKeywordIndex + 1 ..< keywordIndex] {
if case let .identifier(name) = token, name != "_" {
localNames.insert(token.unescaped())
@@ -841,7 +841,7 @@ private struct Inference {
index = formatter.endOfScope(at: index) ?? (formatter.tokens.count - 1)
case .startOfScope("("):
if case let .identifier(fn)? = formatter.last(.nonSpaceOrCommentOrLinebreak, before: index),
selfRequired.contains(fn)
selfRequired.contains(fn)
{
index = formatter.index(of: .endOfScope(")"), after: index) ?? index
break
@@ -866,9 +866,9 @@ private struct Inference {
lastKeyword = ""
var localNames = localNames
guard let keywordIndex = formatter.index(of: .keyword, before: index),
let prevKeywordIndex = formatter.index(of: .keyword, before: keywordIndex),
let prevKeywordToken = formatter.token(at: prevKeywordIndex),
case .keyword("for") = prevKeywordToken else { return }
let prevKeywordIndex = formatter.index(of: .keyword, before: keywordIndex),
let prevKeywordToken = formatter.token(at: prevKeywordIndex),
case .keyword("for") = prevKeywordToken else { return }
for token in formatter.tokens[prevKeywordIndex + 1 ..< keywordIndex] {
if case let .identifier(name) = token, name != "_" {
localNames.insert(token.unescaped())
@@ -961,11 +961,11 @@ private struct Inference {
index = formatter.endOfScope(at: index) ?? (formatter.tokens.count - 1)
case .identifier("self"):
guard !isTypeRoot, !localNames.contains("self"),
let dotIndex = formatter.index(of: .nonSpaceOrLinebreak, after: index, if: {
$0 == .operator(".", .infix)
}), let nextIndex = formatter.index(of: .nonSpaceOrLinebreak, after: dotIndex, if: {
$0.isIdentifier && !localNames.contains($0.unescaped())
})
let dotIndex = formatter.index(of: .nonSpaceOrLinebreak, after: index, if: {
$0 == .operator(".", .infix)
}), let nextIndex = formatter.index(of: .nonSpaceOrLinebreak, after: dotIndex, if: {
$0.isIdentifier && !localNames.contains($0.unescaped())
})
else {
break
}
@@ -998,7 +998,7 @@ private struct Inference {
}
let isAssignment: Bool
if ["for", "var", "let"].contains(lastKeyword),
let prevToken = formatter.last(.nonSpaceOrCommentOrLinebreak, before: index)
let prevToken = formatter.last(.nonSpaceOrCommentOrLinebreak, before: index)
{
switch prevToken {
case .identifier, .number,
@@ -1024,7 +1024,7 @@ private struct Inference {
break
}
if let lastToken = formatter.last(.nonSpaceOrCommentOrLinebreak, before: index),
lastToken.isOperator(".")
lastToken.isOperator(".")
{
break
}
@@ -1130,7 +1130,7 @@ private struct Inference {
let startToken = formatter.tokens[index]
var localNames = localNames
guard let startIndex = formatter.index(of: .startOfScope("("), after: index),
let endIndex = formatter.index(of: .endOfScope(")"), after: startIndex)
let endIndex = formatter.index(of: .endOfScope(")"), after: startIndex)
else {
index += 1 // Prevent endless loop
return
@@ -1139,7 +1139,7 @@ private struct Inference {
index = startIndex
while index < endIndex {
guard let externalNameIndex = formatter.index(of: .identifier, after: index),
let nextIndex = formatter.index(of: .nonSpaceOrCommentOrLinebreak, after: externalNameIndex)
let nextIndex = formatter.index(of: .nonSpaceOrCommentOrLinebreak, after: externalNameIndex)
else { break }
let token = formatter.tokens[nextIndex]
switch token {
@@ -1215,8 +1215,8 @@ private struct Inference {
var space = 0, nospace = 0
formatter.forEach(.operator) { i, token in
guard case .operator(_, .none) = token,
formatter.last(.nonSpaceOrCommentOrLinebreak, before: i) == .keyword("func"),
let token = formatter.token(at: i + 1)
formatter.last(.nonSpaceOrCommentOrLinebreak, before: i) == .keyword("func"),
let token = formatter.token(at: i + 1)
else {
return
}
@@ -1239,7 +1239,7 @@ private struct Inference {
}) else { return }
// Check this isn't an inline block
guard let prevBraceIndex = formatter.index(of: .startOfScope("{"), before: braceIndex),
formatter.lastIndex(of: .linebreak, in: prevBraceIndex + 1 ..< braceIndex) != nil
formatter.lastIndex(of: .linebreak, in: prevBraceIndex + 1 ..< braceIndex) != nil
else {
return
}
@@ -1264,9 +1264,9 @@ private struct Inference {
switchIndent = space
}
guard let openBraceIndex = formatter.index(of: .startOfScope("{"), after: i),
let caseIndex = formatter.index(of: .endOfScope("case"), after: openBraceIndex) ??
formatter.index(of: .endOfScope("default"), after: openBraceIndex),
let indentToken = formatter.token(at: caseIndex - 1)
let caseIndex = formatter.index(of: .endOfScope("case"), after: openBraceIndex) ??
formatter.index(of: .endOfScope("default"), after: openBraceIndex),
let indentToken = formatter.token(at: caseIndex - 1)
else {
return
}
@@ -1288,8 +1288,8 @@ private extension Formatter {
var beforeFirst = 0, afterFirst = 0
forEachToken(where: { [.startOfScope("("), .startOfScope("<")].contains($0) }) { i, _ in
guard isParameterList(at: i) == parameters,
let closingBraceIndex = endOfScope(at: i),
index(of: .linebreak, in: i + 1 ..< closingBraceIndex) != nil
let closingBraceIndex = endOfScope(at: i),
index(of: .linebreak, in: i + 1 ..< closingBraceIndex) != nil
else {
return
}
@@ -1313,7 +1313,7 @@ private extension Formatter {
var beforeFirst = 0, afterFirst = 0
forEachToken(where: { $0.isStartOfScope && scopes.contains($0.string) }) { i, _ in
guard let closingBraceIndex = endOfScope(at: i),
index(of: .linebreak, in: i + 1 ..< closingBraceIndex) != nil
index(of: .linebreak, in: i + 1 ..< closingBraceIndex) != nil
else {
return
}
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.46.3</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+2 -2
View File
@@ -221,8 +221,8 @@ public enum Grouping: Equatable, RawRepresentable, CustomStringConvertible {
$0.trimmingCharacters(in: .whitespacesAndNewlines)
}
guard (1 ... 2).contains(parts.count),
let group = parts.first.flatMap(Int.init),
let threshold = parts.last.flatMap(Int.init)
let group = parts.first.flatMap(Int.init),
let threshold = parts.last.flatMap(Int.init)
else {
return nil
}
+58 -58
View File
@@ -73,7 +73,7 @@ public extension Formatter {
switch token {
case .keyword("#colorLiteral"), .keyword("#imageLiteral"):
guard let startIndex = self.index(of: .startOfScope("("), after: index),
let endIndex = endOfScope(at: startIndex)
let endIndex = endOfScope(at: startIndex)
else {
fallthrough
}
@@ -111,7 +111,7 @@ public extension Formatter {
result += string
case .keyword("#colorLiteral"), .keyword("#imageLiteral"):
guard let startIndex = self.index(of: .startOfScope("("), after: index),
let endIndex = endOfScope(at: startIndex)
let endIndex = endOfScope(at: startIndex)
else {
fallthrough
}
@@ -179,7 +179,7 @@ public extension Formatter {
case .keyword("as"):
wasOperator = true
if case let .operator(name, .postfix)? = self.token(at: i + 1),
["?", "!"].contains(name)
["?", "!"].contains(name)
{
i += 1
}
@@ -223,9 +223,9 @@ extension Formatter {
}
case .endOfScope(")"):
guard let startIndex = self.index(of: .startOfScope("("), before: prevIndex),
last(.nonSpaceOrCommentOrLinebreak, before: startIndex, if: {
$0.isAttribute || _FormatRules.aclModifiers.contains($0.string)
}) != nil
last(.nonSpaceOrCommentOrLinebreak, before: startIndex, if: {
$0.isAttribute || _FormatRules.aclModifiers.contains($0.string)
}) != nil
else {
return false
}
@@ -358,8 +358,8 @@ extension Formatter {
if isConditionalStatement(at: i) {
if let endIndex = endOfScope(at: i),
next(.nonSpaceOrComment, after: endIndex) == .startOfScope("(") ||
next(.nonSpaceOrCommentOrLinebreak, after: endIndex) == .startOfScope("{")
next(.nonSpaceOrComment, after: endIndex) == .startOfScope("(") ||
next(.nonSpaceOrCommentOrLinebreak, after: endIndex) == .startOfScope("{")
{
return true
}
@@ -384,7 +384,7 @@ extension Formatter {
return !isStartOfClosure(at: startOfScope)
case .endOfScope(")"), .endOfScope(">"):
guard var startOfScope = index(of: .startOfScope, before: prevIndex),
var prev = index(of: .nonSpaceOrCommentOrLinebreak, before: startOfScope)
var prev = index(of: .nonSpaceOrCommentOrLinebreak, before: startOfScope)
else {
return true
}
@@ -409,7 +409,7 @@ extension Formatter {
return false
default:
if let nextIndex = index(of: .nonSpaceOrCommentOrLinebreak, after: i),
isAccessorKeyword(at: nextIndex) || isAccessorKeyword(at: prevIndex)
isAccessorKeyword(at: nextIndex) || isAccessorKeyword(at: prevIndex)
{
return false
} else {
@@ -419,7 +419,7 @@ extension Formatter {
fallthrough
case .endOfScope where tokens[prevIndex].isStringDelimiter, .identifier, .number:
if let nextIndex = index(of: .nonSpaceOrCommentOrLinebreak, after: i),
isAccessorKeyword(at: nextIndex) || isAccessorKeyword(at: prevIndex)
isAccessorKeyword(at: nextIndex) || isAccessorKeyword(at: prevIndex)
{
return false
}
@@ -433,7 +433,7 @@ extension Formatter {
}
var index = prevKeywordIndex
while let nextIndex = self.index(of: .nonSpaceOrComment, after: index),
nextIndex < i
nextIndex < i
{
switch tokens[nextIndex] {
case .operator("=", .infix):
@@ -445,7 +445,7 @@ extension Formatter {
return true
}
if tokens[nextIndex] != .startOfScope("{"),
isEndOfStatement(at: index), isStartOfStatement(at: nextIndex)
isEndOfStatement(at: index), isStartOfStatement(at: nextIndex)
{
return true
}
@@ -498,13 +498,13 @@ extension Formatter {
return false
}
if tokens[prevIndex] == .endOfScope("}"),
let startIndex = index(of: .startOfScope("{"), before: prevIndex),
let prev = index(of: .nonSpaceOrCommentOrLinebreak, before: startIndex)
let startIndex = index(of: .startOfScope("{"), before: prevIndex),
let prev = index(of: .nonSpaceOrCommentOrLinebreak, before: startIndex)
{
prevIndex = prev
if tokens[prevIndex] == .endOfScope(")"),
let startIndex = index(of: .startOfScope("("), before: prevIndex),
let prev = index(of: .nonSpaceOrCommentOrLinebreak, before: startIndex)
let startIndex = index(of: .startOfScope("("), before: prevIndex),
let prev = index(of: .nonSpaceOrCommentOrLinebreak, before: startIndex)
{
prevIndex = prev
}
@@ -561,7 +561,7 @@ extension Formatter {
func lastSignificantKeyword(at i: Int, excluding: [String] = []) -> String? {
guard let index = indexOfLastSignificantKeyword(at: i, excluding: excluding),
case let .keyword(keyword) = tokens[index]
case let .keyword(keyword) = tokens[index]
else {
return nil
}
@@ -570,8 +570,8 @@ extension Formatter {
func indexOfLastSignificantKeyword(at i: Int, excluding: [String] = []) -> Int? {
guard let token = token(at: i),
let index = token.isKeyword ? i : index(of: .keyword, before: i),
case let .keyword(keyword) = tokens[index]
let index = token.isKeyword ? i : index(of: .keyword, before: i),
case let .keyword(keyword) = tokens[index]
else {
return nil
}
@@ -583,8 +583,8 @@ extension Formatter {
return indexOfLastSignificantKeyword(at: index - 1, excluding: excluding)
default:
guard let braceIndex = self.index(of: .startOfScope("{"), in: index ..< i),
let endIndex = endOfScope(at: braceIndex),
next(.nonSpaceOrComment, after: endIndex) != .startOfScope("(")
let endIndex = endOfScope(at: braceIndex),
next(.nonSpaceOrComment, after: endIndex) != .startOfScope("(")
else {
return index
}
@@ -608,8 +608,8 @@ extension Formatter {
return i
case .endOfScope(")"):
guard let openParenIndex = index(of: .startOfScope("("), before: i),
let prevTokenIndex = index(of: .nonSpaceOrComment, before: openParenIndex),
tokens[prevTokenIndex].isAttribute
let prevTokenIndex = index(of: .nonSpaceOrComment, before: openParenIndex),
tokens[prevTokenIndex].isAttribute
else {
return nil
}
@@ -673,7 +673,7 @@ extension Formatter {
}
default:
if let attributeIndex = startOfAttribute(at: i),
let prevIndex = index(of: .nonSpaceOrCommentOrLinebreak, before: attributeIndex)
let prevIndex = index(of: .nonSpaceOrCommentOrLinebreak, before: attributeIndex)
{
return isEndOfStatement(at: prevIndex, in: scope)
}
@@ -711,8 +711,8 @@ extension Formatter {
return false
case .startOfScope("{") where isStartOfClosure(at: i):
guard last(.nonSpaceOrComment, before: i)?.isLinebreak == true,
let prevIndex = index(of: .nonSpaceOrCommentOrLinebreak, before: i),
let prevToken = self.token(at: prevIndex)
let prevIndex = index(of: .nonSpaceOrCommentOrLinebreak, before: i),
let prevToken = self.token(at: prevIndex)
else {
return false
}
@@ -720,9 +720,9 @@ extension Formatter {
return false
}
if [.endOfScope(")"), .endOfScope("]")].contains(prevToken),
let startIndex = index(of: .startOfScope, before: prevIndex),
!tokens[startIndex ..< prevIndex].contains(where: { $0.isLinebreak })
|| indentForLine(at: startIndex) == indentForLine(at: prevIndex)
let startIndex = index(of: .startOfScope, before: prevIndex),
!tokens[startIndex ..< prevIndex].contains(where: { $0.isLinebreak })
|| indentForLine(at: startIndex) == indentForLine(at: prevIndex)
{
return false
}
@@ -734,7 +734,7 @@ extension Formatter {
func isSubscriptOrFunctionCall(at i: Int) -> Bool {
guard case let .startOfScope(string)? = token(at: i), ["[", "("].contains(string),
let prevToken = last(.nonSpaceOrComment, before: i)
let prevToken = last(.nonSpaceOrComment, before: i)
else {
return false
}
@@ -771,8 +771,8 @@ extension Formatter {
return false
}
if tokens[prevIndex] == .identifier("View"),
let prevToken = last(.nonSpaceOrCommentOrLinebreak, before: prevIndex),
[.delimiter(":"), .identifier("some")].contains(prevToken)
let prevToken = last(.nonSpaceOrCommentOrLinebreak, before: prevIndex),
[.delimiter(":"), .identifier("some")].contains(prevToken)
{
return true
}
@@ -795,7 +795,7 @@ extension Formatter {
}
case "Self", "Any":
if let prevToken = last(.nonSpaceOrCommentOrLinebreak, before: i),
[.delimiter(":"), .operator("->", .infix)].contains(prevToken)
[.delimiter(":"), .operator("->", .infix)].contains(prevToken)
{
// TODO: check for other cases where it's safe to use unescaped
return false
@@ -865,8 +865,8 @@ extension Formatter {
func isParameterList(at i: Int) -> Bool {
assert([.startOfScope("("), .startOfScope("<")].contains(tokens[i]))
if let endIndex = endOfScope(at: i),
let nextToken = next(.nonSpaceOrCommentOrLinebreak, after: endIndex),
[.operator("->", .infix), .keyword("throws"), .keyword("rethrows")].contains(nextToken)
let nextToken = next(.nonSpaceOrCommentOrLinebreak, after: endIndex),
[.operator("->", .infix), .keyword("throws"), .keyword("rethrows")].contains(nextToken)
{
return true
}
@@ -930,8 +930,8 @@ extension Formatter {
// Gather comments
var prevIndex = index(of: .linebreak, before: startIndex) ?? 0
while startIndex > 0,
next(.nonSpace, after: prevIndex)?.isComment == true,
next(.nonSpaceOrComment, after: prevIndex)?.isLinebreak == true
next(.nonSpace, after: prevIndex)?.isComment == true,
next(.nonSpaceOrComment, after: prevIndex)?.isLinebreak == true
{
if prevIndex == 0, index(of: .startOfScope("#if"), before: startIndex) != nil {
break
@@ -1084,8 +1084,8 @@ extension Formatter {
var index = index
while token(at: index + 1)?.string == ".",
let nextIdentifier = token(at: index + 2),
nextIdentifier.is(.identifier) == true
let nextIdentifier = token(at: index + 2),
nextIdentifier.is(.identifier) == true
{
name = "\(name).\(nextIdentifier.string)"
index += 2
@@ -1097,13 +1097,13 @@ extension Formatter {
// get type of declaration starting at index of declaration keyword
func declarationType(at index: Int) -> String? {
guard let token = self.token(at: index), token.isDeclarationTypeKeyword,
case let .keyword(keyword) = token
case let .keyword(keyword) = token
else {
return nil
}
if keyword == "class",
let nextToken = next(.nonSpaceOrCommentOrLinebreak, after: index),
nextToken.isDeclarationTypeKeyword, case let .keyword(keyword) = nextToken
let nextToken = next(.nonSpaceOrCommentOrLinebreak, after: index),
nextToken.isDeclarationTypeKeyword, case let .keyword(keyword) = nextToken
{
return keyword
}
@@ -1184,7 +1184,7 @@ extension Formatter {
// For conditional compilation blocks, the `declarationKeyword` _is_ the `startOfScope`
// so we can immediately skip to the corresponding #endif
if declarationKeyword == "#if",
let endOfConditionalCompilationScope = parser.endOfScope(at: searchIndex)
let endOfConditionalCompilationScope = parser.endOfScope(at: searchIndex)
{
searchIndex = endOfConditionalCompilationScope
}
@@ -1192,8 +1192,8 @@ extension Formatter {
// Symbol imports (like `import class Module.Type`) will have an extra `isDeclarationTypeKeyword`
// immediately following their `declarationKeyword`, so we need to skip them.
if declarationKeyword == "import",
let symbolTypeKeywordIndex = parser.index(of: .nonSpaceOrComment, after: declarationTypeKeywordIndex),
parser.tokens[symbolTypeKeywordIndex].isDeclarationTypeKeyword
let symbolTypeKeywordIndex = parser.index(of: .nonSpaceOrComment, after: declarationTypeKeywordIndex),
parser.tokens[symbolTypeKeywordIndex].isDeclarationTypeKeyword
{
searchIndex = symbolTypeKeywordIndex + 1
}
@@ -1206,9 +1206,9 @@ extension Formatter {
// - `#if` tokens are `startOfScope`, but immediately represent the start of a new
// conditional compilation declaration so we can't skip through them.
if parser.tokens[searchIndex].isStartOfScope,
!parser.tokens[searchIndex].isComment,
parser.tokens[searchIndex].string != "#if",
let endOfScope = parser.endOfScope(at: searchIndex)
!parser.tokens[searchIndex].isComment,
parser.tokens[searchIndex].string != "#if",
let endOfScope = parser.endOfScope(at: searchIndex)
{
searchIndex = endOfScope + 1
} else if parser.tokens[searchIndex].isDeclarationTypeKeyword
@@ -1240,7 +1240,7 @@ extension Formatter {
while searchIndex > declarationTypeKeywordIndex, startOfScope == nil {
if parser.tokens[searchIndex].isStartOfScope,
parser.endOfScope(at: searchIndex) == encounteredEndOfScope
parser.endOfScope(at: searchIndex) == encounteredEndOfScope
{
startOfScope = searchIndex
// Confirm whether or not this scope should be grouped with the
@@ -1278,7 +1278,7 @@ extension Formatter {
// Prefer keeping linebreaks at the end of a declaration's tokens,
// instead of the start of the next delaration's tokens
while let linebreakSearchIndex = endOfDeclaration,
parser.token(at: linebreakSearchIndex + 1)?.isLinebreak == true
parser.token(at: linebreakSearchIndex + 1)?.isLinebreak == true
{
endOfDeclaration = linebreakSearchIndex + 1
}
@@ -1320,11 +1320,11 @@ extension Formatter {
let typelikeKeywords = ["class", "struct", "enum", "protocol", "extension"]
if typelikeKeywords.contains(declaration.keyword),
let declarationTypeKeywordIndex = declarationParser
.index(after: -1, where: { $0.string == declaration.keyword }),
let startOfBody = declarationParser
.index(of: .startOfScope("{"), after: declarationTypeKeywordIndex),
let endOfBody = declarationParser.endOfScope(at: startOfBody)
let declarationTypeKeywordIndex = declarationParser
.index(after: -1, where: { $0.string == declaration.keyword }),
let startOfBody = declarationParser
.index(of: .startOfScope("{"), after: declarationTypeKeywordIndex),
let endOfBody = declarationParser.endOfScope(at: startOfBody)
{
let (startTokens, bodyDeclarations, endTokens) = parseBody(in: startOfBody ... endOfBody)
@@ -1406,7 +1406,7 @@ extension Formatter {
func addBreakPoint(at i: Int, relativePriority: Int) {
guard stringLiteralDepth == 0, currentPriority + relativePriority >= lastBreakPointPriority,
!isInClosureArguments(at: i + 1)
!isInClosureArguments(at: i + 1)
else {
return
}
@@ -1427,7 +1427,7 @@ extension Formatter {
return nil
case .keyword("#colorLiteral"), .keyword("#imageLiteral"):
guard let startIndex = self.index(of: .startOfScope("("), after: i),
let endIndex = endOfScope(at: startIndex)
let endIndex = endOfScope(at: startIndex)
else {
return nil // error
}
+304 -304
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -32,7 +32,7 @@
import Foundation
/// The current SwiftFormat version
let swiftFormatVersion = "0.46.3"
let swiftFormatVersion = "0.47.0"
public let version = swiftFormatVersion
/// The standard SwiftFormat config file name
@@ -150,7 +150,7 @@ public func enumerateFiles(withInputURL inputURL: URL,
do {
let resourceValues = try getResourceValues(for: inputURL.standardizedFileURL, keys: keys)
if !fileOptions.followSymlinks,
resourceValues.isAliasFile == true || resourceValues.isSymbolicLink == true
resourceValues.isAliasFile == true || resourceValues.isSymbolicLink == true
{
return [FormatError.options("Symbolic link or alias was skipped: \(inputURL.path)")]
}
@@ -161,7 +161,7 @@ public func enumerateFiles(withInputURL inputURL: URL,
return []
}
if resourceValues.isDirectory == false,
!fileOptions.supportedFileExtensions.contains(inputURL.pathExtension)
!fileOptions.supportedFileExtensions.contains(inputURL.pathExtension)
{
return [FormatError.options("Unsupported file type: \(inputURL.path)")]
}
@@ -298,7 +298,7 @@ private func shouldSkipFile(_ inputURL: URL, with options: Options) -> Bool {
continue
}
if let unexcluded = options.fileOptions?.unexcludedGlobs,
unexcluded.contains(where: { $0.matches(path) })
unexcluded.contains(where: { $0.matches(path) })
{
return false
}
@@ -506,14 +506,14 @@ private func applyRules(
// Check if required FileInfo is available
if rules.contains(FormatRules.fileHeader) {
if options.fileHeader.rawValue.contains("{created"),
options.fileInfo.creationDate == nil
options.fileInfo.creationDate == nil
{
throw FormatError.options(
"Failed to apply {created} template in file header as file info is unavailable"
)
}
if options.fileHeader.rawValue.contains("{file"),
options.fileInfo.fileName == nil
options.fileInfo.fileName == nil
{
throw FormatError.options(
"Failed to apply {file} template in file header as file name was not provided"
+25 -25
View File
@@ -2,7 +2,7 @@
// Tokenizer.swift
// SwiftFormat
//
// Version 0.46.3
// Version 0.47.0
//
// Created by Nick Lockwood on 11/08/2016.
// Copyright 2016 Nick Lockwood
@@ -261,10 +261,10 @@ public extension Token {
output.append("\'")
case "u":
guard input.read("{"),
let hex = input.readCharacters(where: { $0.isHexDigit }),
input.read("}"),
let codepoint = Int(hex, radix: 16),
let c = UnicodeScalar(codepoint)
let hex = input.readCharacters(where: { $0.isHexDigit }),
input.read("}"),
let codepoint = Int(hex, radix: 16),
let c = UnicodeScalar(codepoint)
else {
// Invalid. Recover and continue
continue
@@ -1118,8 +1118,8 @@ public func tokenize(_ source: String) -> [Token] {
for index in (scopeIndexStack.last! ..< tokens.count - 1).reversed() {
let nextToken = tokens[index + 1]
guard case let .space(indent) = tokens[index], tokens[index - 1].isLinebreak,
(nextToken.isMultilineStringDelimiter && nextToken.isEndOfScope) ||
nextToken.isStringBody
(nextToken.isMultilineStringDelimiter && nextToken.isEndOfScope) ||
nextToken.isStringBody
else {
if nextToken.isMultilineStringDelimiter, nextToken.isStartOfScope {
offsetStack.removeLast()
@@ -1246,7 +1246,7 @@ public func tokenize(_ source: String) -> [Token] {
}
for index in range.reversed() {
guard case let .space(indent) = tokens[index], tokens[index - 1].isLinebreak,
indent.hasPrefix(baseIndent)
indent.hasPrefix(baseIndent)
else {
continue
}
@@ -1315,7 +1315,7 @@ public func tokenize(_ source: String) -> [Token] {
tokens[i] = .operator(">", .none)
stitchOperators(at: i)
if let previousIndex = index(of: .nonSpaceOrComment, before: i),
tokens[previousIndex] == .endOfScope(">")
tokens[previousIndex] == .endOfScope(">")
{
convertClosingChevronToOperator(at: previousIndex, andOpeningChevron: true)
}
@@ -1340,8 +1340,8 @@ public func tokenize(_ source: String) -> [Token] {
return
}
while let nextToken: Token = index + 1 < tokens.count ? tokens[index + 1] : nil,
case let .operator(nextString, _) = nextToken,
string.hasPrefix(".") || !nextString.contains(".")
case let .operator(nextString, _) = nextToken,
string.hasPrefix(".") || !nextString.contains(".")
{
if scopeIndexStack.last == index {
// In case of a ? previously interpreted as a ternary
@@ -1353,8 +1353,8 @@ public func tokenize(_ source: String) -> [Token] {
}
var index = index
while let prevToken: Token = index > 0 ? tokens[index - 1] : nil,
case let .operator(prevString, _) = prevToken, !isUnwrapOperator(at: index - 1),
prevString.hasPrefix(".") || !string.contains(".")
case let .operator(prevString, _) = prevToken, !isUnwrapOperator(at: index - 1),
prevString.hasPrefix(".") || !string.contains(".")
{
if scopeIndexStack.last == index - 1 {
// In case of a ? previously interpreted as a ternary
@@ -1477,7 +1477,7 @@ public func tokenize(_ source: String) -> [Token] {
case let .keyword(string):
// Track switch/case statements
if let prevIndex = index(of: .nonSpaceOrCommentOrLinebreak, before: count - 1),
case .operator(".", _) = tokens[prevIndex]
case .operator(".", _) = tokens[prevIndex]
{
tokens[tokens.count - 1] = .identifier(string)
processToken()
@@ -1501,9 +1501,9 @@ public func tokenize(_ source: String) -> [Token] {
stitchOperators(at: count - 1)
case .startOfScope("<") where count >= 2:
if tokens[count - 2].isOperator,
index(of: .nonSpaceOrCommentOrLinebreak, before: count - 2).map({
![.keyword("func"), .keyword("init")].contains(tokens[$0])
}) ?? true
index(of: .nonSpaceOrCommentOrLinebreak, before: count - 2).map({
![.keyword("func"), .keyword("init")].contains(tokens[$0])
}) ?? true
{
tokens[tokens.count - 1] = .operator("<", .none)
stitchOperators(at: count - 1)
@@ -1525,17 +1525,17 @@ public func tokenize(_ source: String) -> [Token] {
}
if !token.isSpaceOrCommentOrLinebreak {
if let prevIndex = index(of: .nonSpaceOrComment, before: count - 1),
case .endOfScope(">") = tokens[prevIndex]
case .endOfScope(">") = tokens[prevIndex]
{
// Fix up misidentified generic that is actually a pair of operators
switch token {
case .operator("=", _) where prevIndex == count - 2:
guard let startIndex = index(of: .startOfScope, before: count - 1),
tokens[startIndex] == .startOfScope("<"),
let prevIndex = index(of: .nonSpaceOrComment, before: startIndex),
case .identifier = tokens[prevIndex],
let prevPrevIndex = index(of: .nonSpaceOrCommentOrLinebreak, before: prevIndex),
tokens[prevPrevIndex] == .delimiter(":")
tokens[startIndex] == .startOfScope("<"),
let prevIndex = index(of: .nonSpaceOrComment, before: startIndex),
case .identifier = tokens[prevIndex],
let prevPrevIndex = index(of: .nonSpaceOrCommentOrLinebreak, before: prevIndex),
tokens[prevPrevIndex] == .delimiter(":")
else {
fallthrough
}
@@ -1655,7 +1655,7 @@ public func tokenize(_ source: String) -> [Token] {
if let keywordIndex = index(of: .keyword, before: scopeIndex) {
var keyword = tokens[keywordIndex]
if case .keyword("where") = keyword,
let keywordIndex = index(of: .keyword, before: keywordIndex)
let keywordIndex = index(of: .keyword, before: keywordIndex)
{
keyword = tokens[keywordIndex]
}
@@ -1718,7 +1718,7 @@ public func tokenize(_ source: String) -> [Token] {
return
case let .endOfScope(string):
if ["case", "default"].contains(string), let scopeIndex = scopeIndexStack.last,
tokens[scopeIndex] == .startOfScope("#if")
tokens[scopeIndex] == .startOfScope("#if")
{
scopeIndexStack.append(tokens.count - 1)
return
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "SwiftFormat",
"version": "0.46.3",
"version": "0.47.0",
"license": {
"type": "MIT",
"file": "LICENSE.md"
@@ -10,7 +10,7 @@
"authors": "Nick Lockwood",
"source": {
"git": "https://github.com/nicklockwood/SwiftFormat.git",
"tag": "0.46.3"
"tag": "0.47.0"
},
"default_subspecs": "Core",
"subspecs": [
@@ -24,7 +24,7 @@
"platforms": {
"ios": "7.0",
"tvos": "9.0",
"osx": "10.9"
"osx": "10.12"
}
}
],
+12 -8
View File
@@ -1043,7 +1043,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
@@ -1098,7 +1098,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
@@ -1122,6 +1122,7 @@
INFOPLIST_FILE = Sources/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 0.47.0;
PRODUCT_BUNDLE_IDENTIFIER = com.charcoaldesign.SwiftFormat;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -1145,6 +1146,7 @@
INFOPLIST_FILE = Sources/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 0.47.0;
PRODUCT_BUNDLE_IDENTIFIER = com.charcoaldesign.SwiftFormat;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -1219,8 +1221,8 @@
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = EditorExtension/Application/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
MARKETING_VERSION = 0.46.3;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MARKETING_VERSION = 0.47.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.charcoaldesign.SwiftFormat-for-Xcode";
PRODUCT_NAME = "SwiftFormat for Xcode";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1246,8 +1248,8 @@
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = EditorExtension/Application/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
MARKETING_VERSION = 0.46.3;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MARKETING_VERSION = 0.47.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.charcoaldesign.SwiftFormat-for-Xcode";
PRODUCT_NAME = "SwiftFormat for Xcode";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1270,7 +1272,8 @@
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = EditorExtension/Extension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks";
MARKETING_VERSION = 0.46.3;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MARKETING_VERSION = 0.47.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.charcoaldesign.SwiftFormat-for-Xcode.SourceEditorExtension";
PRODUCT_NAME = SwiftFormat;
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1295,7 +1298,8 @@
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = EditorExtension/Extension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks";
MARKETING_VERSION = 0.46.3;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MARKETING_VERSION = 0.47.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.charcoaldesign.SwiftFormat-for-Xcode.SourceEditorExtension";
PRODUCT_NAME = SwiftFormat;
PROVISIONING_PROFILE_SPECIFIER = "";
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>0.46.3</string>
<string>0.47.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+6 -6
View File
@@ -103,10 +103,10 @@ class MetadataTests: XCTestCase {
var rulesByOption = [String: String]()
formatter.forEach(.identifier("FormatRule")) { i, _ in
guard formatter.next(.nonSpaceOrLinebreak, after: i) == .startOfScope("("),
case let .identifier(name)? = formatter.last(.identifier, before: i),
let scopeStart = formatter.index(of: .startOfScope("{"), after: i),
let scopeEnd = formatter.index(of: .endOfScope("}"), after: scopeStart),
let rule = FormatRules.byName[name]
case let .identifier(name)? = formatter.last(.identifier, before: i),
let scopeStart = formatter.index(of: .startOfScope("{"), after: i),
let scopeEnd = formatter.index(of: .endOfScope("}"), after: scopeStart),
let rule = FormatRules.byName[name]
else {
return
}
@@ -120,7 +120,7 @@ class MetadataTests: XCTestCase {
var referencedOptions = [OptionDescriptor]()
for index in scopeStart + 1 ..< scopeEnd {
guard formatter.token(at: index - 1) == .operator(".", .infix),
formatter.token(at: index - 2) == .identifier("formatter")
formatter.token(at: index - 2) == .identifier("formatter")
else {
continue
}
@@ -156,7 +156,7 @@ class MetadataTests: XCTestCase {
referencedOptions.append(Descriptors.modifierOrder)
case .identifier("options") where formatter.token(at: index + 1) == .operator(".", .infix):
if case let .identifier(property)? = formatter.token(at: index + 2),
let option = optionsByProperty[property]
let option = optionsByProperty[property]
{
referencedOptions.append(option)
}