@@ -13,41 +13,65 @@ class ImmutableMappableCommand: NSObject, XCSourceEditorCommand {
13
13
14
14
func perform( with invocation: XCSourceEditorCommandInvocation , completionHandler: @escaping ( Error ? ) -> Void ) -> Void {
15
15
16
+
16
17
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 {
32
24
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 \n extension %@: 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
+ }
43
68
}
44
-
45
- newString += " \n \t } "
46
- newString += " \n } \n \n "
47
69
}
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 ) }
53
77
}
0 commit comments