mirror of
https://github.com/nicklockwood/SwiftFormat.git
synced 2026-06-16 10:34:34 +00:00
Reverted 0.6 release
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
// SwiftFormat
|
||||
// main.swift
|
||||
//
|
||||
// Version 0.6
|
||||
// Version 0.5.1
|
||||
//
|
||||
// Created by Nick Lockwood on 12/08/2016.
|
||||
// Copyright 2016 Charcoal Design
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
let version = "0.6"
|
||||
let version = "0.5.1"
|
||||
|
||||
func processInput(inputURL: NSURL, andWriteToOutput outputURL: NSURL, withOptions options: FormattingOptions) -> Int {
|
||||
let manager = NSFileManager.defaultManager()
|
||||
|
||||
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
||||
SwiftFormat
|
||||
|
||||
Version 0.6, August 26th, 2016
|
||||
Version 0.5.1, August 25th, 2016
|
||||
|
||||
Copyright (c) 2016 Nick Lockwood
|
||||
|
||||
|
||||
@@ -192,8 +192,6 @@ Here are all the rules that SwiftFormat currently applies:
|
||||
return; --> return;
|
||||
goto(fail) goto(fail)
|
||||
|
||||
*linebreaks* - normalizes all linebreaks to use the same character, as specified in options (either CR, LF or CRLF).
|
||||
|
||||
|
||||
FAQ
|
||||
-----
|
||||
@@ -324,11 +322,6 @@ With a syntax tree in place, it should become possible to add much more sophisti
|
||||
Release notes
|
||||
----------------
|
||||
|
||||
Version 0.6
|
||||
|
||||
- Refactored how switch/case is handled, and fixed a bunch of bugs
|
||||
- Better indenting logic, now handles multiple closure arguments in a single function call
|
||||
|
||||
Version 0.5.1
|
||||
|
||||
- Fixed critical bug where double unwrap (e.g. `foo??.bar()`) was not handled correctly
|
||||
|
||||
+162
-144
@@ -2,7 +2,7 @@
|
||||
// SwiftFormat
|
||||
// Formatter.swift
|
||||
//
|
||||
// Version 0.6
|
||||
// Version 0.5.1
|
||||
//
|
||||
// Created by Nick Lockwood on 12/08/2016.
|
||||
// Copyright 2016 Charcoal Design
|
||||
@@ -67,8 +67,6 @@ public class Formatter {
|
||||
self.options = options
|
||||
}
|
||||
|
||||
// MARK: access and mutation
|
||||
|
||||
/// Returns the token at the specified index, or nil if index is invalid
|
||||
public func tokenAtIndex(index: Int) -> Token? {
|
||||
guard index >= 0 && index < tokens.count else { return nil }
|
||||
@@ -134,8 +132,6 @@ public class Formatter {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: enumeration
|
||||
|
||||
/// Loops through each token in the array. It is safe to mutate the token
|
||||
/// array inside the body block, but note that the index and token arguments
|
||||
/// may not reflect the current token any more after a mutation
|
||||
@@ -150,33 +146,34 @@ public class Formatter {
|
||||
indexStack.popLast()
|
||||
}
|
||||
|
||||
/// As above, but only loops through tokens that match the specified filter block
|
||||
public func forEachToken(matching: (Token) -> Bool, _ body: (Int, Token) -> Void) {
|
||||
forEachToken { index, token in
|
||||
if matching(token) {
|
||||
body(index, token)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// As above, but only loops through tokens with the specified type
|
||||
public func forEachToken(ofType type: TokenType, _ body: (Int, Token) -> Void) {
|
||||
forEachToken({ $0.type == type }, body)
|
||||
forEachToken(matching: { $0.type == type }, body)
|
||||
}
|
||||
|
||||
/// As above, but only loops through tokens with the specified type and string
|
||||
public func forEachToken(string: String, ofType type: TokenType, _ body: (Int, Token) -> Void) {
|
||||
forEachToken({ return $0.type == type && $0.string == string }, body)
|
||||
forEachToken(matching: {
|
||||
return $0.type == type && $0.string == string
|
||||
}, body)
|
||||
}
|
||||
|
||||
/// As above, but only loops through tokens with the specified string.
|
||||
/// Tokens of type `StringBody` and `CommentBody` are ignored, as these
|
||||
/// can't be usefully identified by their string value
|
||||
public func forEachToken(string: String, _ body: (Int, Token) -> Void) {
|
||||
forEachToken({
|
||||
forEachToken(matching: {
|
||||
return $0.string == string && $0.type != .StringBody && $0.type != .CommentBody
|
||||
}, body)
|
||||
}
|
||||
|
||||
private func forEachToken(matching condition: (Token) -> Bool, _ body: (Int, Token) -> Void) {
|
||||
forEachToken { index, token in
|
||||
if condition(token) {
|
||||
body(index, token)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public typealias FormatRule = (Formatter) -> Void
|
||||
@@ -193,22 +190,22 @@ public func spaceAroundParens(formatter: Formatter) {
|
||||
func spaceAfter(identifier: String) -> Bool {
|
||||
switch identifier {
|
||||
case "internal",
|
||||
"case",
|
||||
"for",
|
||||
"guard",
|
||||
"if",
|
||||
"in",
|
||||
"return",
|
||||
"switch",
|
||||
"where",
|
||||
"while",
|
||||
"as",
|
||||
"catch",
|
||||
"is",
|
||||
"rethrows",
|
||||
"throw",
|
||||
"throws",
|
||||
"try":
|
||||
"case",
|
||||
"for",
|
||||
"guard",
|
||||
"if",
|
||||
"in",
|
||||
"return",
|
||||
"switch",
|
||||
"where",
|
||||
"while",
|
||||
"as",
|
||||
"catch",
|
||||
"is",
|
||||
"rethrows",
|
||||
"throw",
|
||||
"throws",
|
||||
"try":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -268,15 +265,15 @@ public func spaceAroundBrackets(formatter: Formatter) {
|
||||
func spaceAfter(identifier: String) -> Bool {
|
||||
switch identifier {
|
||||
case "case",
|
||||
"guard",
|
||||
"if",
|
||||
"in",
|
||||
"return",
|
||||
"switch",
|
||||
"where",
|
||||
"while",
|
||||
"as",
|
||||
"is":
|
||||
"guard",
|
||||
"if",
|
||||
"in",
|
||||
"return",
|
||||
"switch",
|
||||
"where",
|
||||
"while",
|
||||
"as",
|
||||
"is":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -432,16 +429,16 @@ public func spaceAroundOperators(formatter: Formatter) {
|
||||
func spaceAfter(identifier: String) -> Bool {
|
||||
switch identifier {
|
||||
case "case",
|
||||
"guard",
|
||||
"if",
|
||||
"in",
|
||||
"let",
|
||||
"return",
|
||||
"switch",
|
||||
"where",
|
||||
"while",
|
||||
"as",
|
||||
"is":
|
||||
"guard",
|
||||
"if",
|
||||
"in",
|
||||
"let",
|
||||
"return",
|
||||
"switch",
|
||||
"where",
|
||||
"while",
|
||||
"as",
|
||||
"is":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -507,7 +504,8 @@ public func spaceAroundOperators(formatter: Formatter) {
|
||||
(previousNonWhitespaceToken.string != "?" &&
|
||||
formatter.tokenAtIndex(previousNonWhitespaceTokenIndex - 1)?.type != .Whitespace &&
|
||||
isUnwrapOperatorSequence(previousNonWhitespaceToken))) &&
|
||||
!spaceAfter(previousNonWhitespaceToken.string) {
|
||||
(previousNonWhitespaceToken.type != .Identifier ||
|
||||
!spaceAfter(previousNonWhitespaceToken.string)) {
|
||||
if previousTokenWasWhitespace {
|
||||
formatter.removeTokenAtIndex(i - 1)
|
||||
}
|
||||
@@ -567,13 +565,9 @@ public func noConsecutiveSpaces(formatter: Formatter) {
|
||||
|
||||
formatter.forEachToken(ofType: .Whitespace) { i, token in
|
||||
if let previousToken = formatter.tokenAtIndex(i - 1) where previousToken.type != .Linebreak {
|
||||
if token.string == "" {
|
||||
formatter.removeTokenAtIndex(i)
|
||||
} else if token.string != " " {
|
||||
let scope = currentScopeAtIndex(i)
|
||||
if scope?.string != "/*" && scope?.string != "//" {
|
||||
formatter.replaceTokenAtIndex(i, with: Token(.Whitespace, " "))
|
||||
}
|
||||
let scope = currentScopeAtIndex(i)
|
||||
if scope?.string != "/*" && scope?.string != "//" {
|
||||
formatter.replaceTokenAtIndex(i, with: Token(.Whitespace, " "))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -654,13 +648,15 @@ public func indent(formatter: Formatter) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func setIndent(indent: String, atIndex index: Int) -> Bool {
|
||||
func setIndent(indent: String, atIndex index: Int) {
|
||||
if formatter.tokenAtIndex(index)?.type == .Whitespace {
|
||||
formatter.replaceTokenAtIndex(index, with: Token(.Whitespace, indent))
|
||||
return false
|
||||
} else {
|
||||
if indent != "" {
|
||||
formatter.replaceTokenAtIndex(index, with: Token(.Whitespace, indent))
|
||||
} else {
|
||||
formatter.removeTokenAtIndex(index)
|
||||
}
|
||||
} else if indent != "" {
|
||||
formatter.insertToken(Token(.Whitespace, indent), atIndex: index)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -682,50 +678,50 @@ public func indent(formatter: Formatter) {
|
||||
func tokenIsEndOfStatement(i: Int) -> Bool {
|
||||
if let token = formatter.tokenAtIndex(i) {
|
||||
switch token.type {
|
||||
case .Identifier, .EndOfScope:
|
||||
case .Identifier:
|
||||
// TODO: handle context-specific keywords
|
||||
// in, associativity, convenience, dynamic, didSet, final, get, infix, indirect,
|
||||
// lazy, left, mutating, none, nonmutating, optional, override, postfix, precedence,
|
||||
// prefix, Protocol, required, right, set, Type, unowned, weak, willSet
|
||||
switch token.string {
|
||||
case "associatedtype",
|
||||
"class",
|
||||
"deinit",
|
||||
"enum",
|
||||
"extension",
|
||||
"fileprivate",
|
||||
"func",
|
||||
"import",
|
||||
"init",
|
||||
"inout",
|
||||
"internal",
|
||||
"let",
|
||||
"open",
|
||||
"operator",
|
||||
"private",
|
||||
"protocol",
|
||||
"public",
|
||||
"static",
|
||||
"struct",
|
||||
"subscript",
|
||||
"typealias",
|
||||
"var",
|
||||
"case",
|
||||
"default",
|
||||
"defer",
|
||||
"else",
|
||||
"for",
|
||||
"guard",
|
||||
"if",
|
||||
"switch",
|
||||
"where",
|
||||
"while",
|
||||
"as",
|
||||
"catch",
|
||||
"is",
|
||||
"super",
|
||||
"throw",
|
||||
"try":
|
||||
"class",
|
||||
"deinit",
|
||||
"enum",
|
||||
"extension",
|
||||
"fileprivate",
|
||||
"func",
|
||||
"import",
|
||||
"init",
|
||||
"inout",
|
||||
"internal",
|
||||
"let",
|
||||
"open",
|
||||
"operator",
|
||||
"private",
|
||||
"protocol",
|
||||
"public",
|
||||
"static",
|
||||
"struct",
|
||||
"subscript",
|
||||
"typealias",
|
||||
"var",
|
||||
"case",
|
||||
"default",
|
||||
"defer",
|
||||
"else",
|
||||
"for",
|
||||
"guard",
|
||||
"if",
|
||||
"switch",
|
||||
"where",
|
||||
"while",
|
||||
"as",
|
||||
"catch",
|
||||
"is",
|
||||
"super",
|
||||
"throw",
|
||||
"try":
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
@@ -756,13 +752,13 @@ public func indent(formatter: Formatter) {
|
||||
// TODO: handle "in"
|
||||
switch token.string {
|
||||
case "as",
|
||||
"dynamicType",
|
||||
"false",
|
||||
"is",
|
||||
"nil",
|
||||
"rethrows",
|
||||
"throws",
|
||||
"true":
|
||||
"dynamicType",
|
||||
"false",
|
||||
"is",
|
||||
"nil",
|
||||
"rethrows",
|
||||
"throws",
|
||||
"true":
|
||||
return false
|
||||
case "else":
|
||||
if let token = formatter.tokenAtIndex(lastNonWhitespaceOrLinebreakIndex) {
|
||||
@@ -790,71 +786,96 @@ public func indent(formatter: Formatter) {
|
||||
return true
|
||||
}
|
||||
|
||||
setIndent("", atIndex: 0)
|
||||
formatter.forEachToken { i, token in
|
||||
var i = i
|
||||
if token.type == .StartOfScope {
|
||||
// Handle start of scope
|
||||
scopeIndexStack.append(i)
|
||||
var indent = indentStack.last ?? ""
|
||||
switch token.string {
|
||||
case "/*":
|
||||
// Comments only indent one space
|
||||
indent += " "
|
||||
case "//", "\"":
|
||||
// No need to indent
|
||||
break
|
||||
default:
|
||||
if lineIndex > scopeStartLineIndexes.last ?? -1 {
|
||||
indent += formatter.options.indent
|
||||
if lineIndex > scopeStartLineIndexes.last ?? -1 {
|
||||
if token.string == "/*" {
|
||||
// Comments only indent one space
|
||||
indent += " "
|
||||
} else {
|
||||
indentStack.popLast()
|
||||
indentStack.append(indentStack.last ?? "")
|
||||
indent += formatter.options.indent
|
||||
}
|
||||
}
|
||||
indentStack.append(indent)
|
||||
scopeStartLineIndexes.append(lineIndex)
|
||||
} else if token.type != .Whitespace {
|
||||
} else {
|
||||
if let scopeIndex = scopeIndexStack.last, scope = formatter.tokenAtIndex(scopeIndex) {
|
||||
// Handle end of scope
|
||||
if token.closesScopeForToken(scope) {
|
||||
scopeStartLineIndexes.popLast()
|
||||
scopeIndexStack.popLast()
|
||||
indentStack.popLast()
|
||||
if lineIndex > scopeStartLineIndexes.last ?? -1 { // What is this?
|
||||
if lineIndex > scopeStartLineIndexes.last ?? -1 {
|
||||
let start = startOfLine(atIndex: i)
|
||||
if let nextToken = nextNonWhitespaceToken(fromIndex: start) where
|
||||
nextToken.type == .EndOfScope && nextToken.string != "*/" {
|
||||
// Only reduce indent if line begins with a closing scope token
|
||||
let indent = indentStack.last ?? ""
|
||||
if setIndent(indent, atIndex: start) {
|
||||
i += 1
|
||||
}
|
||||
setIndent(indent, atIndex: start)
|
||||
}
|
||||
}
|
||||
} else if token.type == .Identifier {
|
||||
// Handle #elseif/#else
|
||||
if token.string == "#else" || token.string == "#elseif" {
|
||||
let indent = indentStack[indentStack.count - 2]
|
||||
if setIndent(indent, atIndex: startOfLine(atIndex: i)) {
|
||||
i += 1
|
||||
setIndent(indent, atIndex: startOfLine(atIndex: i))
|
||||
}
|
||||
// Handle switch/case
|
||||
else if token.string == "case" || token.string == "default" {
|
||||
if formatter.tokenAtIndex(lastNonWhitespaceIndex)?.string == "if" {
|
||||
// it was an if case statement
|
||||
} else if scope.string == "{" {
|
||||
// walk backwards to see if this is an switch or enum
|
||||
var isSwitch = true
|
||||
var subscopeStack: [Token] = []
|
||||
var j = scopeIndex - 1
|
||||
loop: while let token = formatter.tokenAtIndex(j) {
|
||||
switch token.type {
|
||||
case .Identifier:
|
||||
if subscopeStack.count == 0 {
|
||||
if token.string == "switch" {
|
||||
break loop
|
||||
}
|
||||
if token.string == "enum" {
|
||||
isSwitch = false
|
||||
break loop
|
||||
}
|
||||
}
|
||||
case .EndOfScope:
|
||||
subscopeStack.append(token)
|
||||
case .StartOfScope:
|
||||
if subscopeStack.count == 0 {
|
||||
break loop
|
||||
}
|
||||
subscopeStack.popLast()
|
||||
default:
|
||||
break
|
||||
}
|
||||
j -= 1
|
||||
}
|
||||
if isSwitch {
|
||||
let indent = indentStack[indentStack.count - 2]
|
||||
setIndent(indent, atIndex: startOfLine(atIndex: i))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Indent each new line
|
||||
if token.type == .Linebreak {
|
||||
var indent = indentStack.last ?? ""
|
||||
linewrapped = !tokenIsEndOfStatement(lastNonWhitespaceOrLinebreakIndex)
|
||||
if linewrapped && lineIndex == scopeStartLineIndexes.last {
|
||||
indent = indentStack.count > 1 ? indentStack[indentStack.count - 2] : ""
|
||||
scopeStartLineIndexes[scopeStartLineIndexes.count - 1] += 1
|
||||
indentStack.popLast()
|
||||
indentStack.append(indentStack.last ?? "")
|
||||
}
|
||||
lineIndex += 1
|
||||
setIndent("", atIndex: i + 1)
|
||||
// Only indent if line isn't blank
|
||||
if let nextToken = formatter.tokenAtIndex(i + 2) where nextToken.type != .Linebreak {
|
||||
indent += (linewrapped ? formatter.options.indent : "")
|
||||
if let nextToken = formatter.tokenAtIndex(i + 1) where nextToken.type != .Linebreak {
|
||||
let indent = (indentStack.last ?? "") + (linewrapped ? formatter.options.indent : "")
|
||||
setIndent(indent, atIndex: i + 1)
|
||||
}
|
||||
}
|
||||
@@ -864,15 +885,12 @@ public func indent(formatter: Formatter) {
|
||||
if !linewrapped && formatter.tokenAtIndex(lastNonWhitespaceIndex)?.type == .Linebreak &&
|
||||
!tokenIsStartOfStatement(i) {
|
||||
linewrapped = true
|
||||
var indent = indentStack.last ?? ""
|
||||
if lineIndex - 1 == scopeStartLineIndexes.last {
|
||||
indent = indentStack.count > 1 ? indentStack[indentStack.count - 2] : ""
|
||||
scopeStartLineIndexes[scopeStartLineIndexes.count - 1] += 1
|
||||
}
|
||||
indent += (linewrapped ? formatter.options.indent : "")
|
||||
if setIndent(indent, atIndex: startOfLine(atIndex: i)) {
|
||||
i += 1
|
||||
if linewrapped && lineIndex - 1 == scopeStartLineIndexes.last {
|
||||
indentStack.popLast()
|
||||
indentStack.append(indentStack.last ?? "")
|
||||
}
|
||||
let indent = (indentStack.last ?? "") + (linewrapped ? formatter.options.indent : "")
|
||||
setIndent(indent, atIndex: startOfLine(atIndex: i))
|
||||
}
|
||||
lastNonWhitespaceIndex = i
|
||||
if token.type != .Linebreak {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SwiftFormat
|
||||
// SwiftFormat.h
|
||||
//
|
||||
// Version 0.6
|
||||
// Version 0.5.1
|
||||
//
|
||||
// Created by Nick Lockwood on 12/08/2016.
|
||||
// Copyright 2016 Charcoal Design
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SwiftFormat
|
||||
// SwiftFormat.swift
|
||||
//
|
||||
// Version 0.6
|
||||
// Version 0.5.1
|
||||
//
|
||||
// Created by Nick Lockwood on 12/08/2016.
|
||||
// Copyright 2016 Charcoal Design
|
||||
|
||||
+81
-111
@@ -2,7 +2,7 @@
|
||||
// SwiftFormat
|
||||
// Tokenizer.swift
|
||||
//
|
||||
// Version 0.6
|
||||
// Version 0.5.1
|
||||
//
|
||||
// Created by Nick Lockwood on 11/08/2016.
|
||||
// Copyright 2016 Charcoal Design
|
||||
@@ -74,34 +74,26 @@ public struct Token: Equatable {
|
||||
}
|
||||
|
||||
public func closesScopeForToken(token: Token) -> Bool {
|
||||
guard token.type == .StartOfScope else {
|
||||
guard type != .StringBody && type != .CommentBody else {
|
||||
return false
|
||||
}
|
||||
if type == .EndOfScope {
|
||||
switch token.string {
|
||||
case "(":
|
||||
return string == ")"
|
||||
case "[":
|
||||
return string == "]"
|
||||
case "{":
|
||||
return string == "}" || string == "case" || string == "default"
|
||||
case "/*":
|
||||
return string == "*/"
|
||||
case "#if":
|
||||
return string == "#endif"
|
||||
case ":":
|
||||
return string == "case" || string == "default" || string == "}"
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
switch token.string {
|
||||
case "(":
|
||||
return string == ")"
|
||||
case "[":
|
||||
return string == "]"
|
||||
case "{":
|
||||
return string == "}"
|
||||
case "<":
|
||||
return string.hasPrefix(">")
|
||||
case "\"":
|
||||
return string == "\""
|
||||
case "/*":
|
||||
return string == "*/"
|
||||
case "//":
|
||||
return type == .Linebreak
|
||||
case "#if":
|
||||
return string == "#endif"
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@@ -203,20 +195,20 @@ private extension String.CharacterView {
|
||||
}
|
||||
switch c.unicodeValue {
|
||||
case 0x00A1 ... 0x00A7,
|
||||
0x00A9, 0x00AB, 0x00AC, 0x00AE,
|
||||
0x00B0 ... 0x00B1,
|
||||
0x00B6, 0x00BB, 0x00BF, 0x00D7, 0x00F7,
|
||||
0x2016 ... 0x2017,
|
||||
0x2020 ... 0x2027,
|
||||
0x2030 ... 0x203E,
|
||||
0x2041 ... 0x2053,
|
||||
0x2055 ... 0x205E,
|
||||
0x2190 ... 0x23FF,
|
||||
0x2500 ... 0x2775,
|
||||
0x2794 ... 0x2BFF,
|
||||
0x2E00 ... 0x2E7F,
|
||||
0x3001 ... 0x3003,
|
||||
0x3008 ... 0x3030:
|
||||
0x00A9, 0x00AB, 0x00AC, 0x00AE,
|
||||
0x00B0 ... 0x00B1,
|
||||
0x00B6, 0x00BB, 0x00BF, 0x00D7, 0x00F7,
|
||||
0x2016 ... 0x2017,
|
||||
0x2020 ... 0x2027,
|
||||
0x2030 ... 0x203E,
|
||||
0x2041 ... 0x2053,
|
||||
0x2055 ... 0x205E,
|
||||
0x2190 ... 0x23FF,
|
||||
0x2500 ... 0x2775,
|
||||
0x2794 ... 0x2BFF,
|
||||
0x2E00 ... 0x2E7F,
|
||||
0x3001 ... 0x3003,
|
||||
0x3008 ... 0x3030:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -229,11 +221,11 @@ private extension String.CharacterView {
|
||||
}
|
||||
switch c.unicodeValue {
|
||||
case 0x0300 ... 0x036F,
|
||||
0x1DC0 ... 0x1DFF,
|
||||
0x20D0 ... 0x20FF,
|
||||
0xFE00 ... 0xFE0F,
|
||||
0xFE20 ... 0xFE2F,
|
||||
0xE0100 ... 0xE01EF:
|
||||
0x1DC0 ... 0x1DFF,
|
||||
0x20D0 ... 0x20FF,
|
||||
0xFE00 ... 0xFE0F,
|
||||
0xFE20 ... 0xFE2F,
|
||||
0xE0100 ... 0xE01EF:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -278,51 +270,51 @@ private extension String.CharacterView {
|
||||
}
|
||||
switch c.unicodeValue {
|
||||
case 0x00A8, 0x00AA, 0x00AD, 0x00AF,
|
||||
0x00B2 ... 0x00B5,
|
||||
0x00B7 ... 0x00BA,
|
||||
0x00BC ... 0x00BE,
|
||||
0x00C0 ... 0x00D6,
|
||||
0x00D8 ... 0x00F6,
|
||||
0x00F8 ... 0x00FF,
|
||||
0x0100 ... 0x02FF,
|
||||
0x0370 ... 0x167F,
|
||||
0x1681 ... 0x180D,
|
||||
0x180F ... 0x1DBF,
|
||||
0x1E00 ... 0x1FFF,
|
||||
0x200B ... 0x200D,
|
||||
0x202A ... 0x202E,
|
||||
0x203F ... 0x2040,
|
||||
0x2054,
|
||||
0x2060 ... 0x206F,
|
||||
0x2070 ... 0x20CF,
|
||||
0x2100 ... 0x218F,
|
||||
0x2460 ... 0x24FF,
|
||||
0x2776 ... 0x2793,
|
||||
0x2C00 ... 0x2DFF,
|
||||
0x2E80 ... 0x2FFF,
|
||||
0x3004 ... 0x3007,
|
||||
0x3021 ... 0x302F,
|
||||
0x3031 ... 0x303F,
|
||||
0x3040 ... 0xD7FF,
|
||||
0xF900 ... 0xFD3D,
|
||||
0xFD40 ... 0xFDCF,
|
||||
0xFDF0 ... 0xFE1F,
|
||||
0xFE30 ... 0xFE44,
|
||||
0xFE47 ... 0xFFFD,
|
||||
0x10000 ... 0x1FFFD,
|
||||
0x20000 ... 0x2FFFD,
|
||||
0x30000 ... 0x3FFFD,
|
||||
0x40000 ... 0x4FFFD,
|
||||
0x50000 ... 0x5FFFD,
|
||||
0x60000 ... 0x6FFFD,
|
||||
0x70000 ... 0x7FFFD,
|
||||
0x80000 ... 0x8FFFD,
|
||||
0x90000 ... 0x9FFFD,
|
||||
0xA0000 ... 0xAFFFD,
|
||||
0xB0000 ... 0xBFFFD,
|
||||
0xC0000 ... 0xCFFFD,
|
||||
0xD0000 ... 0xDFFFD,
|
||||
0xE0000 ... 0xEFFFD:
|
||||
0x00B2 ... 0x00B5,
|
||||
0x00B7 ... 0x00BA,
|
||||
0x00BC ... 0x00BE,
|
||||
0x00C0 ... 0x00D6,
|
||||
0x00D8 ... 0x00F6,
|
||||
0x00F8 ... 0x00FF,
|
||||
0x0100 ... 0x02FF,
|
||||
0x0370 ... 0x167F,
|
||||
0x1681 ... 0x180D,
|
||||
0x180F ... 0x1DBF,
|
||||
0x1E00 ... 0x1FFF,
|
||||
0x200B ... 0x200D,
|
||||
0x202A ... 0x202E,
|
||||
0x203F ... 0x2040,
|
||||
0x2054,
|
||||
0x2060 ... 0x206F,
|
||||
0x2070 ... 0x20CF,
|
||||
0x2100 ... 0x218F,
|
||||
0x2460 ... 0x24FF,
|
||||
0x2776 ... 0x2793,
|
||||
0x2C00 ... 0x2DFF,
|
||||
0x2E80 ... 0x2FFF,
|
||||
0x3004 ... 0x3007,
|
||||
0x3021 ... 0x302F,
|
||||
0x3031 ... 0x303F,
|
||||
0x3040 ... 0xD7FF,
|
||||
0xF900 ... 0xFD3D,
|
||||
0xFD40 ... 0xFDCF,
|
||||
0xFDF0 ... 0xFE1F,
|
||||
0xFE30 ... 0xFE44,
|
||||
0xFE47 ... 0xFFFD,
|
||||
0x10000 ... 0x1FFFD,
|
||||
0x20000 ... 0x2FFFD,
|
||||
0x30000 ... 0x3FFFD,
|
||||
0x40000 ... 0x4FFFD,
|
||||
0x50000 ... 0x5FFFD,
|
||||
0x60000 ... 0x6FFFD,
|
||||
0x70000 ... 0x7FFFD,
|
||||
0x80000 ... 0x8FFFD,
|
||||
0x90000 ... 0x9FFFD,
|
||||
0xA0000 ... 0xAFFFD,
|
||||
0xB0000 ... 0xBFFFD,
|
||||
0xC0000 ... 0xCFFFD,
|
||||
0xD0000 ... 0xDFFFD,
|
||||
0xE0000 ... 0xEFFFD:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -335,9 +327,9 @@ private extension String.CharacterView {
|
||||
}
|
||||
switch c.unicodeValue {
|
||||
case 0x0300 ... 0x036F,
|
||||
0x1DC0 ... 0x1DFF,
|
||||
0x20D0 ... 0x20FF,
|
||||
0xFE20 ... 0xFE2F:
|
||||
0x1DC0 ... 0x1DFF,
|
||||
0x20D0 ... 0x20FF,
|
||||
0xFE20 ... 0xFE2F:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -427,8 +419,6 @@ func tokenize(source: String) -> [Token] {
|
||||
var characters = source.characters
|
||||
var lastNonWhitespaceIndex: Int?
|
||||
var closedGenericScopeIndexes: [Int] = []
|
||||
var nestedSwitches = 0
|
||||
var inCaseStatement = false
|
||||
|
||||
func processStringBody() {
|
||||
var string = ""
|
||||
@@ -544,25 +534,6 @@ func tokenize(source: String) -> [Token] {
|
||||
func processToken() {
|
||||
let token = tokens.last!
|
||||
if token.type != .Whitespace {
|
||||
// Track switch/case statements
|
||||
if token.type == .Identifier {
|
||||
if token.string == "switch" {
|
||||
nestedSwitches += 1
|
||||
} else if nestedSwitches > 0 && (token.string == "case" || token.string == "default") {
|
||||
let lastToken = tokens[lastNonWhitespaceIndex!]
|
||||
if lastToken.string != "if" {
|
||||
tokens[tokens.count - 1] = Token(.EndOfScope, token.string)
|
||||
inCaseStatement = true
|
||||
processToken()
|
||||
return
|
||||
}
|
||||
}
|
||||
} else if inCaseStatement && token.type == .Operator && token.string == ":" {
|
||||
tokens[tokens.count - 1] = Token(.StartOfScope, ":")
|
||||
inCaseStatement = false
|
||||
processToken()
|
||||
return
|
||||
}
|
||||
// Fix up misidentified generic that is actually a pair of operators
|
||||
if let lastNonWhitespaceIndex = lastNonWhitespaceIndex {
|
||||
let lastToken = tokens[lastNonWhitespaceIndex]
|
||||
@@ -617,9 +588,7 @@ func tokenize(source: String) -> [Token] {
|
||||
let scope = tokens[scopeIndex]
|
||||
if token.closesScopeForToken(scope) {
|
||||
scopeIndexStack.popLast()
|
||||
if token.string == "}" && scope.string == ":" {
|
||||
nestedSwitches -= 1
|
||||
} else if token.string.hasPrefix(">") {
|
||||
if token.string.hasPrefix(">") {
|
||||
closedGenericScopeIndexes.append(scopeIndex)
|
||||
tokens[tokens.count - 1] = Token(.EndOfScope, ">")
|
||||
if token.string != ">" {
|
||||
@@ -629,6 +598,7 @@ func tokenize(source: String) -> [Token] {
|
||||
processToken()
|
||||
return
|
||||
}
|
||||
|
||||
} else if scopeIndexStack.last != nil && tokens[scopeIndexStack.last!].string == "\"" {
|
||||
processStringBody()
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SwiftFormat
|
||||
// FormatterTests.swift
|
||||
//
|
||||
// Version 0.6
|
||||
// Version 0.5.1
|
||||
//
|
||||
// Created by Nick Lockwood on 12/08/2016.
|
||||
// Copyright 2016 Charcoal Design
|
||||
@@ -360,12 +360,6 @@ class FormatterTests: XCTestCase {
|
||||
XCTAssertEqual(format(input, rules: [spaceAroundOperators]), output)
|
||||
}
|
||||
|
||||
func testSwitchWithEnumCases() {
|
||||
let input = "switch x {\ncase.Foo:\nbreak\ndefault:\n break\n}"
|
||||
let output = "switch x {\ncase .Foo:\nbreak\ndefault:\n break\n}"
|
||||
XCTAssertEqual(format(input, rules: [spaceAroundOperators]), output)
|
||||
}
|
||||
|
||||
func testSpaceAroundEnumReturn() {
|
||||
let input = "return.Foo"
|
||||
let output = "return .Foo"
|
||||
@@ -624,18 +618,6 @@ class FormatterTests: XCTestCase {
|
||||
XCTAssertEqual(format(input, rules: [indent]), output)
|
||||
}
|
||||
|
||||
func testNestedBraces() {
|
||||
let input = "({\n//foo\n}, {\n//bar\n})"
|
||||
let output = "({\n //foo\n}, {\n //bar\n})"
|
||||
XCTAssertEqual(format(input, rules: [indent]), output)
|
||||
}
|
||||
|
||||
func testBraceIndentAfterComment() {
|
||||
let input = "if foo { //comment\nbar\n}"
|
||||
let output = "if foo { //comment\n bar\n}"
|
||||
XCTAssertEqual(format(input, rules: [indent]), output)
|
||||
}
|
||||
|
||||
// MARK: indent switch/case
|
||||
|
||||
func testSwitchCaseIndenting() {
|
||||
@@ -644,12 +626,6 @@ class FormatterTests: XCTestCase {
|
||||
XCTAssertEqual(format(input, rules: [indent]), output)
|
||||
}
|
||||
|
||||
func testSwitchWrappedCaseIndenting() {
|
||||
let input = "switch x {\ncase foo,\nbar,\n baz:\n break\ndefault:\n break\n}"
|
||||
let output = "switch x {\ncase foo,\n bar,\n baz:\n break\ndefault:\n break\n}"
|
||||
XCTAssertEqual(format(input, rules: [indent]), output)
|
||||
}
|
||||
|
||||
func testEnumCaseIndenting() {
|
||||
let input = "enum Foo {\ncase Bar\ncase Baz\n}"
|
||||
let output = "enum Foo {\n case Bar\n case Baz\n}"
|
||||
@@ -724,12 +700,6 @@ class FormatterTests: XCTestCase {
|
||||
XCTAssertEqual(format(input, rules: [indent]), output)
|
||||
}
|
||||
|
||||
func testNoPermanentReductionInScopeAfterWrap() {
|
||||
let input = "{foo\nas Bar\nlet baz = 5\n}"
|
||||
let output = "{foo\n as Bar\n let baz = 5\n}"
|
||||
XCTAssertEqual(format(input, rules: [indent]), output)
|
||||
}
|
||||
|
||||
func testWrappedLineBeforeOperator() {
|
||||
let input = "if x {\nlet y = foo\n+ bar\n}"
|
||||
let output = "if x {\n let y = foo\n + bar\n}"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SwiftFormat
|
||||
// TokenizerTests.swift
|
||||
//
|
||||
// Version 0.6
|
||||
// Version 0.5.1
|
||||
//
|
||||
// Created by Nick Lockwood on 12/08/2016.
|
||||
// Copyright 2016 Charcoal Design
|
||||
@@ -917,104 +917,6 @@ class TokenizerTests: XCTestCase {
|
||||
XCTAssertEqualArrays(tokenize(input), output)
|
||||
}
|
||||
|
||||
// MARK: case statements
|
||||
|
||||
func testSingleLineEnum() {
|
||||
let input = "enum Foo {case Bar, Baz}"
|
||||
let output = [
|
||||
Token(.Identifier, "enum"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.Identifier, "Foo"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.StartOfScope, "{"),
|
||||
Token(.Identifier, "case"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.Identifier, "Bar"),
|
||||
Token(.Operator, ","),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.Identifier, "Baz"),
|
||||
Token(.EndOfScope, "}"),
|
||||
]
|
||||
XCTAssertEqualArrays(tokenize(input), output)
|
||||
}
|
||||
|
||||
func testSingleLineGenericEnum() {
|
||||
let input = "enum Foo<T> {case Bar, Baz}"
|
||||
let output = [
|
||||
Token(.Identifier, "enum"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.Identifier, "Foo"),
|
||||
Token(.StartOfScope, "<"),
|
||||
Token(.Identifier, "T"),
|
||||
Token(.EndOfScope, ">"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.StartOfScope, "{"),
|
||||
Token(.Identifier, "case"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.Identifier, "Bar"),
|
||||
Token(.Operator, ","),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.Identifier, "Baz"),
|
||||
Token(.EndOfScope, "}"),
|
||||
]
|
||||
XCTAssertEqualArrays(tokenize(input), output)
|
||||
}
|
||||
|
||||
func testMultilineLineEnum() {
|
||||
let input = "enum Foo {\ncase Bar\ncase Baz\n}"
|
||||
let output = [
|
||||
Token(.Identifier, "enum"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.Identifier, "Foo"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.StartOfScope, "{"),
|
||||
Token(.Linebreak, "\n"),
|
||||
Token(.Identifier, "case"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.Identifier, "Bar"),
|
||||
Token(.Linebreak, "\n"),
|
||||
Token(.Identifier, "case"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.Identifier, "Baz"),
|
||||
Token(.Linebreak, "\n"),
|
||||
Token(.EndOfScope, "}"),
|
||||
]
|
||||
XCTAssertEqualArrays(tokenize(input), output)
|
||||
}
|
||||
|
||||
func testSwitchStatement() {
|
||||
let input = "switch x {\ncase 1:\nbreak\ncase 2:\nbreak\ndefault:\nbreak\n}"
|
||||
let output = [
|
||||
Token(.Identifier, "switch"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.Identifier, "x"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.StartOfScope, "{"),
|
||||
Token(.Linebreak, "\n"),
|
||||
Token(.EndOfScope, "case"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.Number, "1"),
|
||||
Token(.StartOfScope, ":"),
|
||||
Token(.Linebreak, "\n"),
|
||||
Token(.Identifier, "break"),
|
||||
Token(.Linebreak, "\n"),
|
||||
Token(.EndOfScope, "case"),
|
||||
Token(.Whitespace, " "),
|
||||
Token(.Number, "2"),
|
||||
Token(.StartOfScope, ":"),
|
||||
Token(.Linebreak, "\n"),
|
||||
Token(.Identifier, "break"),
|
||||
Token(.Linebreak, "\n"),
|
||||
Token(.EndOfScope, "default"),
|
||||
Token(.StartOfScope, ":"),
|
||||
Token(.Linebreak, "\n"),
|
||||
Token(.Identifier, "break"),
|
||||
Token(.Linebreak, "\n"),
|
||||
Token(.EndOfScope, "}"),
|
||||
]
|
||||
XCTAssertEqualArrays(tokenize(input), output)
|
||||
}
|
||||
|
||||
// MARK: linebreaks
|
||||
|
||||
func testLF() {
|
||||
|
||||
Reference in New Issue
Block a user