Skip to content

Commit 8786b51

Browse files
liyanhuadev@icloud.comliyanhuadev@icloud.com
authored andcommitted
2016.12.30
1 parent f58748a commit 8786b51

File tree

16 files changed

+667
-452
lines changed

16 files changed

+667
-452
lines changed

ExCommand/ExCommand-Bridging-Header.h

Lines changed: 0 additions & 4 deletions
This file was deleted.

ExCommand/FileParser.swift

Lines changed: 0 additions & 181 deletions
This file was deleted.

ExCommand/ImmutableMappableCommand.swift

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,41 +13,65 @@ class ImmutableMappableCommand: NSObject, XCSourceEditorCommand {
1313

1414
func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void ) -> Void {
1515

16+
1617
let lines = invocation.buffer.lines.flatMap { "\($0)" }
17-
let content = lines.reduce("", +)
18-
let parser = FileParser()
19-
let structModelList = parser.parser(content: content)
20-
21-
var newString = "\n\n"
22-
23-
for structModel in structModelList {
24-
newString += String(format: "extension %@: ImmutableMappable {", structModel.name)
25-
newString += "\n\n\t"
26-
newString += "init(map: Map) throws {"
27-
newString += "\n"
28-
for value in structModel.variables + structModel.constants {
29-
newString += "\n\t\t"
30-
newString += String(format: "%-20s = try map.value(\"%@\")", (value as NSString).utf8String!, value)
31-
}
18+
19+
var classModelImpl: [(Int, String)] = []
20+
21+
let metadatas = Parser().parse(buffer: lines)
22+
23+
for case let Metadata.model(range, elements) in metadatas {
3224

33-
newString += "\n\t}"
34-
newString += "\n\n\t"
35-
newString += "mutating func mapping(map: Map) {"
36-
for value in structModel.variables {
37-
newString += "\n\t\t"
38-
newString += String(format: "%-20s <- map[\"%@\"]", (value as NSString).utf8String!, value)
39-
}
40-
for value in structModel.constants {
41-
newString += "\n\t\t"
42-
newString += String(format: "%-20s >>> map[\"%@\"]", (value as NSString).utf8String!, value)
25+
let modelBuffer = Array(lines[range])
26+
let pattern = ".*(struct|class)\\s+(\\w+)([^{\\n]*)"
27+
if let regex = try? Regex(string: pattern), let matche = regex.match(modelBuffer[0]) {
28+
29+
let isStruct = matche.captures[0] == "struct"
30+
let modelName = matche.captures[1]!
31+
32+
if matche.captures[0] == "class" {
33+
let protocolStr = matche.captures[2]!.contains(":") ? ", ImmutableMappable " : ": ImmutableMappable "
34+
var str = modelBuffer[0]
35+
str.replaceSubrange(matche.range, with: matche.matchedString + protocolStr)
36+
invocation.buffer.lines[range.lowerBound] = str
37+
}
38+
39+
var initial = String(format: "\n\n\t%@ init(map: Map) throws {", isStruct ? "" : "required ")
40+
var mapping = String(format: "\n\n\t%@func mapping(map: Map) {", isStruct ? "mutating " : "")
41+
for case let Metadata.property(lineNumber) in elements {
42+
if let regex = try? Regex(string: "(.*)(let|var)\\s+(\\w+)\\s*:"),
43+
let matche = regex.match(modelBuffer[lineNumber+1]) {
44+
if matche.captures[0]!.contains("static") {
45+
continue
46+
}
47+
let value = matche.captures[2]!
48+
if matche.captures[1] == "var" {
49+
mapping += String(format: "\n\t\t%-20s <- map[\"%@\"]", (value as NSString).utf8String!, value)
50+
} else {
51+
mapping += String(format: "\n\t\t%-20s >>> map[\"%@\"]", (value as NSString).utf8String!, value)
52+
}
53+
54+
initial += String(format: "\n\t\t%-20s = try map.value(\"%@\")", (value as NSString).utf8String!, value)
55+
56+
}
57+
}
58+
initial += "\n\t}"
59+
mapping += "\n\t}"
60+
61+
if isStruct {
62+
let protocolImpl = String(format: "\n\nextension %@: ImmutableMappable {%@%@\n}", modelName, initial, mapping)
63+
invocation.buffer.lines.add(protocolImpl)
64+
} else {
65+
let protocolImpl = String(format: "%@%@", initial, mapping)
66+
classModelImpl.append((range.upperBound-1, protocolImpl))
67+
}
4368
}
44-
45-
newString += "\n\t}"
46-
newString += "\n}\n\n"
4769
}
48-
49-
invocation.buffer.lines.add(newString)
50-
51-
completionHandler(nil)
52-
}
70+
71+
classModelImpl.sort { (args1, args2) -> Bool in return args1.0 > args2.0 }
72+
for (index, impl) in classModelImpl {
73+
invocation.buffer.lines.insert(impl, at: index)
74+
}
75+
76+
completionHandler(nil) }
5377
}

ExCommand/MappableCommand.swift

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,55 @@ class MappableCommand: NSObject, XCSourceEditorCommand {
1414
func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void ) -> Void {
1515

1616
let lines = invocation.buffer.lines.flatMap { "\($0)" }
17-
let content = lines.reduce("", +)
18-
let parser = FileParser()
19-
let structModelList = parser.parser(content: content)
2017

21-
var newString = "\n\n"
18+
var classModelImpl: [(Int, String)] = []
2219

23-
for structModel in structModelList {
24-
newString += String(format: "extension %@: Mappable {", structModel.name)
25-
newString += "\n\n\t"
26-
newString += "init?(map: Map) {"
27-
for value in structModel.constants {
28-
newString += "\n\t\t"
29-
newString += String(format: "%-20s = <#Value#>", (value as NSString).utf8String!)
30-
}
31-
newString += "\n}"
32-
newString += "\n\n\t"
33-
newString += "mutating func mapping(map: Map) {"
34-
for value in structModel.variables {
35-
newString += "\n\t\t"
36-
newString += String(format: "%-20s <- map[\"%@\"]", (value as NSString).utf8String!, value)
37-
}
20+
let metadatas = Parser().parse(buffer: lines)
21+
22+
for case let Metadata.model(range, elements) in metadatas {
3823

39-
newString += "\n\t}"
40-
newString += "\n}"
24+
let modelBuffer = Array(lines[range])
25+
let pattern = ".*(struct|class)\\s+(\\w+)([^{\\n]*)"
26+
if let regex = try? Regex(string: pattern), let matche = regex.match(modelBuffer[0]) {
27+
28+
let isStruct = matche.captures[0] == "struct"
29+
let modelName = matche.captures[1]!
30+
31+
if matche.captures[0] == "class" {
32+
let protocolStr = matche.captures[2]!.contains(":") ? ", Mappable " : ": Mappable "
33+
var str = modelBuffer[0]
34+
str.replaceSubrange(matche.range, with: matche.matchedString + protocolStr)
35+
invocation.buffer.lines[range.lowerBound] = str
36+
}
37+
38+
let initial = String(format: "\n\n\t%@init?(map: Map) {\n\n\t}", isStruct ? "" : "required ")
39+
40+
var mapping = String(format: "\n\n\t%@func mapping(map: Map) {", isStruct ? "mutating " : "")
41+
for case let Metadata.property(lineNumber) in elements {
42+
if let regex = try? Regex(string: "(.*)(let|var)\\s+(\\w+)\\s*:"),
43+
let matche = regex.match(modelBuffer[lineNumber+1]) {
44+
if matche.captures[0]?.contains("static") == false && matche.captures[1] == "var" {
45+
let value = matche.captures[2]!
46+
mapping += String(format: "\n\t\t%-20s <- map[\"%@\"]", (value as NSString).utf8String!, value)
47+
}
48+
}
49+
}
50+
mapping += "\n\t}"
51+
52+
if isStruct {
53+
let protocolImpl = String(format: "\n\nextension %@: Mappable {%@%@\n}", modelName, initial, mapping)
54+
invocation.buffer.lines.add(protocolImpl)
55+
} else {
56+
let protocolImpl = String(format: "%@%@", initial, mapping)
57+
classModelImpl.append((range.upperBound-1, protocolImpl))
58+
}
59+
}
60+
}
61+
62+
classModelImpl.sort { (args1, args2) -> Bool in return args1.0 > args2.0 }
63+
for (index, impl) in classModelImpl {
64+
invocation.buffer.lines.insert(impl, at: index)
4165
}
42-
43-
invocation.buffer.lines.add(newString)
4466

4567
completionHandler(nil)
4668
}

0 commit comments

Comments
 (0)