├── CodeGeneratorTests
├── EquatableClazz.txt
├── GeneratedInit.txt
├── GeneratedEquals.txt
├── funcMock.txt
├── interface1.txt
├── NSObject+file.swift
├── GeneratedHash.txt
├── GeneratedNSCoder.txt
├── Info.plist
├── CodeGeneratorTests.swift
├── AccessLevelTests.swift
├── InitGeneratorTests.swift
├── InterfaceMockerTests.swift
├── HashableGeneratorTest.swift
├── NSCodingGeneratorTest.swift
├── EquatableGeneratorTests.swift
├── VarSignatureTests.swift
├── interface1Mock.txt
├── InterfaceSignatureTests.swift
├── FuncSignatureTests.swift
├── FuncMockTests.swift
└── SwiftTypeTests.swift
├── CodeGenerator.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcshareddata
│ └── xcschemes
│ │ ├── CodeGenerator.xcscheme
│ │ └── Generate....xcscheme
└── project.pbxproj
├── Generate...
├── Generate___.entitlements
├── ParamMocker.swift
├── SourceError.swift
├── Generator.swift
├── GenerateInitCommand.swift
├── GenerateCodingCommand.swift
├── TypeParser.swift
├── GenerateHashableCommand.swift
├── GenerateEquatableCommand.swift
├── SwiftParamMocker.swift
├── ParamMockerFactory.swift
├── SourceEditorExtension.swift
├── GenerateAsExtensionCommand.swift
├── AccessLevel.swift
├── GenerateMockCommand.swift
├── InterfaceDefinition.swift
├── SwiftType.swift
├── GenerateAfterVarCommand.swift
├── String+regexr.swift
├── InitGenerator.swift
├── EquatableGenerator.swift
├── FuncParam.swift
├── InterfaceSignature.swift
├── ClosureType.swift
├── ClosureParamMocker.swift
├── FuncMocker.swift
├── InterfaceMocker.swift
├── HashableGenerator.swift
├── VarSignature.swift
├── Info.plist
├── SelectableGeneratorCommand.swift
├── CodingGenerator.swift
└── FuncSignature.swift
├── CodeGenerator
├── ViewController.swift
├── AppDelegate.swift
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
└── Base.lproj
│ └── Main.storyboard
├── .gitignore
└── README.md
/CodeGeneratorTests/EquatableClazz.txt:
--------------------------------------------------------------------------------
1 | class EquatableClazz {
2 | var var0: TimeInterval
3 | let var1: [String]
4 | var var2: Bool?
5 | }
6 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/GeneratedInit.txt:
--------------------------------------------------------------------------------
1 |
2 | init(var0: TimeInterval, var1: [String], var2: Bool?) {
3 | self.var0 = var0
4 | self.var1 = var1
5 | self.var2 = var2
6 | }
7 |
--------------------------------------------------------------------------------
/CodeGenerator.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/GeneratedEquals.txt:
--------------------------------------------------------------------------------
1 |
2 | extension EquatableClazz: Equatable {
3 | static func ==(lhs: EquatableClazz, rhs: EquatableClazz) -> Bool {
4 | return lhs.var0 == rhs.var0 && lhs.var1 == rhs.var1 && lhs.var2 == rhs.var2
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Generate.../Generate___.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/funcMock.txt:
--------------------------------------------------------------------------------
1 | testFuncMock = funcMock
2 | if testShouldCallSuccessHandler {
3 | testSuccessHandlerDidReturn = successHandler(testSuccessHandlerParam0, testSuccessHandlerParam1)
4 | }
5 | testFuncMockWasCalled = true
6 | testFuncMockWasCalledTimes += 1
7 | return testFuncMockShouldReturn
8 |
--------------------------------------------------------------------------------
/Generate.../ParamMocker.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ParamMocker.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 28/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | protocol ParamMocker {
12 |
13 | var variables: [VarSignature] { get }
14 |
15 | var lines: [String] { get }
16 | }
17 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/interface1.txt:
--------------------------------------------------------------------------------
1 | protocol Pokemon {
2 | var height: Double! { get set }
3 | var canEvolve: Bool! { get }
4 | // var weight: Double!
5 |
6 | func eat(food: String)
7 |
8 | func drink(_ water: String)
9 |
10 | func isFlying() -> Bool
11 |
12 | func evolve(successHandler: @escaping (String) -> Void, failureHandler: (String?) -> String?)
13 | }
14 |
--------------------------------------------------------------------------------
/Generate.../SourceError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SourceError.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 29/06/2017.
6 | // Copyright © 2017 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension NSError {
12 | static let sourceInvalid = NSError(domain: "com.wangjie.CodeGenerator.Generate", code: -1, userInfo: [NSLocalizedDescriptionKey: "source invalid"])
13 | }
14 |
--------------------------------------------------------------------------------
/Generate.../Generator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Generator.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 02/01/2017.
6 | // Copyright © 2017 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | protocol Generator {
12 | var lines: [String] { get }
13 |
14 | init(interfaceSignature: InterfaceSignature, indentation: String)
15 |
16 | init(interfaceDefinition: InterfaceDefinition, varSignatures: [VarSignature], indentation: String)
17 | }
18 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/NSObject+file.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+file.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 26/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension NSObject {
12 |
13 | func string(from path: String, ofType type: String) -> String {
14 | let path = Bundle(for: Swift.type(of: self)).path(forResource: path, ofType: type)!
15 | return try! String(contentsOfFile: path)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/GeneratedHash.txt:
--------------------------------------------------------------------------------
1 |
2 | extension EquatableClazz: Hashable {
3 | static func ==(lhs: EquatableClazz, rhs: EquatableClazz) -> Bool {
4 | return lhs.var0 == rhs.var0 && lhs.var1 == rhs.var1 && lhs.var2 == rhs.var2
5 | }
6 |
7 | var hashValue: Int {
8 | var hashValue = 1
9 | let hashableVars: [AnyHashable?] = [var0, var1, var2]
10 | hashableVars.forEach {
11 | hashValue = 31 * hashValue + ($0?.hashValue ?? 0)
12 | }
13 | return hashValue
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/CodeGenerator/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | class ViewController: NSViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | // Do any additional setup after loading the view.
17 | }
18 |
19 | override var representedObject: Any? {
20 | didSet {
21 | // Update the view, if already loaded.
22 | }
23 | }
24 |
25 |
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/GeneratedNSCoder.txt:
--------------------------------------------------------------------------------
1 |
2 | required init?(coder aDecoder: NSCoder) {
3 | guard let var1 = aDecoder.decodeObject(forKey: "var1") as? [String] else { return nil }
4 | var0 = aDecoder.decodeDouble(forKey: "var0")
5 | self.var1 = var1
6 | if aDecoder.containsValue(forKey: "var2") {
7 | var2 = aDecoder.decodeBool(forKey: "var2")
8 | }
9 | }
10 |
11 | func encode(with aCoder: NSCoder) {
12 | aCoder.encode(var0, forKey: "var0")
13 | aCoder.encode(var1, forKey: "var1")
14 | aCoder.encode(var2, forKey: "var2")
15 | }
16 |
--------------------------------------------------------------------------------
/CodeGenerator/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | @NSApplicationMain
12 | class AppDelegate: NSObject, NSApplicationDelegate {
13 |
14 |
15 |
16 | func applicationDidFinishLaunching(_ aNotification: Notification) {
17 | // Insert code here to initialize your application
18 | }
19 |
20 | func applicationWillTerminate(_ aNotification: Notification) {
21 | // Insert code here to tear down your application
22 | }
23 |
24 |
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/Generate.../GenerateInitCommand.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GenerateInitCommand.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 30/03/2017.
6 | // Copyright © 2017 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | class GenerateInitCommand: NSObject, GenerateAfterVarCommand {
13 |
14 | var generatorType: Generator.Type {
15 | return InitGenerator.self
16 | }
17 |
18 | func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void) {
19 | swiftPerform(with: invocation, completionHandler: completionHandler)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Generate.../GenerateCodingCommand.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GenerateCodingCommand.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 25/05/2017.
6 | // Copyright © 2017 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | class GenerateCodingCommand: NSObject, GenerateAfterVarCommand {
13 |
14 | var generatorType: Generator.Type {
15 | return CodingGenerator.self
16 | }
17 |
18 | func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void) {
19 | swiftPerform(with: invocation, completionHandler: completionHandler)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Generate.../TypeParser.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TypeParser.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 28/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class TypeParser {
12 |
13 | static func parse(string: String) -> SwiftType {
14 | if string.isClosure {
15 | return ClosureType(rawString: string)
16 | }
17 | return SwiftType(rawString: string)
18 | }
19 | }
20 |
21 | private extension String {
22 | var isClosure: Bool {
23 | if contains("->") {
24 | return true
25 | }
26 | return false
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Generate.../GenerateHashableCommand.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GenerateHashableCommand.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 02/01/2017.
6 | // Copyright © 2017 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | class GenerateHashableCommand: NSObject, GenerateAsExtensionCommand {
13 |
14 | var generatorType: Generator.Type {
15 | return HashableGenerator.self
16 | }
17 |
18 | func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void) {
19 | swiftPerform(with: invocation, completionHandler: completionHandler)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Generate.../GenerateEquatableCommand.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GenerateEquatableCommand.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 27/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | class GenerateEquatableCommand: NSObject, GenerateAsExtensionCommand {
13 |
14 | var generatorType: Generator.Type {
15 | return EquatableGenerator.self
16 | }
17 |
18 | func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void) {
19 | swiftPerform(with: invocation, completionHandler: completionHandler)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Generate.../SwiftParamMocker.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftParamMocker.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 28/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct SwiftParamMocker: ParamMocker {
12 |
13 | let param: FuncParam
14 | let funcName: String
15 | let indentation: String
16 |
17 | var variables: [VarSignature] {
18 | return [VarSignature.init(declaration: "var", name: "\(funcName)\(param.name.Capitalized)", type: param.type.optionalName)]
19 | }
20 |
21 | var lines: [String] {
22 | let line = "\(indentation.repeating(2))\(variables[0].name) = \(param.name)"
23 | return [line]
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Generate.../ParamMockerFactory.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ParamMockerFactory.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 29/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct ParamMockerFactory {
12 |
13 | private static let funcMockers: [String: (FuncParam, String, String) -> ParamMocker] = [
14 | String(describing: SwiftType.self): { SwiftParamMocker(param: $0, funcName: $1, indentation: $2) },
15 | String(describing: ClosureType.self): { ClosureParamMocker(param: $0, funcName: $1, indentation: $2) }]
16 |
17 | static func create(funcParam: FuncParam, funcName: String, indentation: String) -> ParamMocker {
18 | return funcMockers[String(describing: type(of: funcParam.type))]!(funcParam, funcName, indentation)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Generate.../SourceEditorExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SourceEditorExtension.swift
3 | // Generate...
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | class SourceEditorExtension: NSObject, XCSourceEditorExtension {
13 |
14 | /*
15 | func extensionDidFinishLaunching() {
16 | // If your extension needs to do any work at launch, implement this optional method.
17 | }
18 | */
19 |
20 | /*
21 | var commandDefinitions: [[XCSourceEditorCommandDefinitionKey: Any]] {
22 | // If your extension needs to return a collection of command definitions that differs from those in its Info.plist, implement this optional property getter.
23 | return []
24 | }
25 | */
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/Generate.../GenerateAsExtensionCommand.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GenerateAsExtensionCommand.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 30/03/2017.
6 | // Copyright © 2017 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | protocol GenerateAsExtensionCommand: SelectableGeneratorCommand {
13 |
14 | }
15 |
16 | extension GenerateAsExtensionCommand {
17 | func generateForAllVariables(with invocation: XCSourceEditorCommandInvocation) throws {
18 | invocation.buffer.lines.addObjects(from: try generator(with: invocation).lines)
19 | }
20 |
21 | func generateForSelectedVariables(with invocation: XCSourceEditorCommandInvocation, selections: [XCSourceTextRange]) throws {
22 | invocation.buffer.lines.addObjects(from: try generator(with: invocation, selections: selections).lines)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Generate.../AccessLevel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AccessLevel.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 27/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | enum AccessLevel: String {
12 | case `open` = "open"
13 | case `public` = "public"
14 | case `internal` = "internal"
15 | case `fileprivate` = "fileprivate"
16 | case `private` = "private"
17 |
18 | init(string: String) {
19 | let allLevels: [AccessLevel] = [.open, .public, .internal, .fileprivate, .private]
20 | for level in allLevels {
21 | if let result = " (\(level)) ".firstMatch(in: string) {
22 | self.init(rawValue: string.substring(with: result.range(at: 1)))!
23 | return
24 | }
25 | }
26 | self.init(rawValue: "internal")!
27 | }
28 |
29 | var isPrivate: Bool {
30 | return self == .private || self == .fileprivate
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Build generated
2 | build/
3 | DerivedData/
4 |
5 | ## Various settings
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata/
15 |
16 | ## Other
17 | *.moved-aside
18 | *.xcuserstate
19 | ## Obj-C/Swift specific
20 | *.hmap
21 | *.ipa
22 | *.dSYM.zip
23 | *.dSYM
24 |
25 | ## Playgrounds
26 | timeline.xctimeline
27 | playground.xcworkspace
28 |
29 | # Swift Package Manager
30 | #
31 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
32 | # Packages/
33 | .build/
34 |
35 | # CocoaPods
36 | #
37 | # We recommend against adding the Pods directory to your .gitignore. However
38 | # you should judge for yourself, the pros and cons are mentioned at:
39 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
40 | #
41 | Pods/
42 | fastlane/README.md
43 | fastlane/report.xml
44 | fastlane/Appfile
45 |
--------------------------------------------------------------------------------
/Generate.../GenerateMockCommand.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GenerateMockCommand.swift
3 | // Generate...
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | class GenerateMockCommand: NSObject, XCSourceEditorCommand {
13 |
14 | func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void ) {
15 | do {
16 | let interfaceSignature = try InterfaceSignature(interfaceSource: invocation.buffer.completeBuffer, lines: invocation.buffer.lines.map { $0 as! String })
17 | let interfaceMocker = InterfaceMocker(interfaceSignature: interfaceSignature, indentationWidth: invocation.buffer.indentationWidth)
18 | invocation.buffer.lines.add("")
19 | invocation.buffer.lines.add("")
20 | invocation.buffer.lines.addObjects(from: interfaceMocker.lines)
21 | completionHandler(nil)
22 | } catch {
23 | completionHandler(error)
24 | }
25 |
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Generate.../InterfaceDefinition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InterfaceDefinition.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct InterfaceDefinition {
12 | let name: String
13 | /// can be class, protocol, extension...
14 | let type: String
15 | let lineIndex: Int
16 |
17 | init(lines: [String]) throws {
18 | for (index, line) in lines.enumerated() {
19 | guard let definition = "(protocol|class|extension|struct) ([A-Za-z]*)".firstMatch(in: line) else {
20 | continue
21 | }
22 | name = line.substring(with: definition.range(at: 2))
23 | type = line.substring(with: definition.range(at: 1))
24 | lineIndex = index
25 | return
26 | }
27 | throw NSError.sourceInvalid
28 | }
29 | }
30 |
31 | extension InterfaceDefinition: Equatable {
32 | static func ==(l: InterfaceDefinition, r: InterfaceDefinition) -> Bool {
33 | return l.name == r.name && l.type == r.type && l.lineIndex == r.lineIndex
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/CodeGeneratorTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CodeGeneratorTests.swift
3 | // CodeGeneratorTests
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CodeGenerator
11 |
12 | class CodeGeneratorTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | // Use XCTAssert and related functions to verify your tests produce the correct results.
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measure {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/CodeGenerator/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/CodeGenerator/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 0.04
21 | CFBundleVersion
22 | 4
23 | LSApplicationCategoryType
24 | public.app-category.developer-tools
25 | LSMinimumSystemVersion
26 | $(MACOSX_DEPLOYMENT_TARGET)
27 | NSHumanReadableCopyright
28 | Copyright © 2016 wangjie. All rights reserved.
29 | NSMainStoryboardFile
30 | Main
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/AccessLevelTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AccessLevelTests.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 27/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CodeGenerator
11 |
12 | class AccessLevelTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testAccessLevel1() {
25 | XCTAssertEqual(AccessLevel(string: " public "), AccessLevel.public)
26 | XCTAssertEqual(AccessLevel(string: " internal var name: String"), AccessLevel.internal)
27 | XCTAssertEqual(AccessLevel(string: " open func"), AccessLevel.open)
28 | XCTAssertEqual(AccessLevel(string: " fileprivate var"), AccessLevel.fileprivate)
29 | XCTAssertEqual(AccessLevel(string: " private var"), AccessLevel.private)
30 | XCTAssertEqual(AccessLevel(string: "public "), AccessLevel.internal)
31 | XCTAssertEqual(AccessLevel(string: " privatevar"), AccessLevel.internal)
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/Generate.../SwiftType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftType.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 28/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class SwiftType {
12 |
13 | static let Void = SwiftType(rawString: "Void")
14 |
15 | let rawString: String
16 |
17 | init(rawString: String) {
18 | self.rawString = rawString.trimed
19 | }
20 |
21 | var name: String {
22 | return rawString
23 | }
24 |
25 | var isSensible: Bool {
26 | return true
27 | }
28 |
29 | var unwrappedName: String {
30 | if isOptional {
31 | return String(name[.. String {
37 | return unwrappedName+wrap
38 | }
39 |
40 | var isOptional: Bool {
41 | guard !name.isEmpty else { return false }
42 | return ("?!").contains(name.last!)
43 | }
44 |
45 | var optionalName: String {
46 | return name(with: "?")
47 | }
48 |
49 | var forceUnwrappedName: String {
50 | return name(with: "!")
51 | }
52 |
53 | }
54 |
55 |
56 | extension SwiftType: Equatable {
57 | static func ==(lhs: SwiftType, rhs: SwiftType) -> Bool {
58 | return lhs.rawString == rhs.rawString
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/InitGeneratorTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InitGeneratorTests.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 30/03/2017.
6 | // Copyright © 2017 wangjie. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CodeGenerator
11 |
12 | class InitGeneratorTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testInitGenerator() {
25 | let source = string(from: "EquatableClazz", ofType: "txt")
26 | let interface = try! InterfaceSignature(interfaceSource: source, lines: source.components(separatedBy: "\n"))
27 | let initGenerator = InitGenerator(interfaceSignature: interface, indentation: " ")
28 |
29 | var expectedHashSource = string(from: "GeneratedInit", ofType: "txt").components(separatedBy: "\n")
30 | expectedHashSource.removeLast()
31 |
32 | XCTAssertEqual(initGenerator.lines.count, expectedHashSource.count)
33 | let count = min(initGenerator.lines.count, expectedHashSource.count)
34 | for i in 0.. Bool?")
31 | XCTAssertEqual(var2, VarSignature(declaration: "let", name: "name", type: "(String) -> Bool?"))
32 | }
33 |
34 | func testVar3() {
35 | let var3 = VarSignature(string: " var name: (String?, Bool) -> (String, Bool?) { get set }")
36 | XCTAssertEqual(var3, VarSignature(declaration: "var", name: "name", type: "(String?, Bool) -> (String, Bool?)"))
37 | }
38 |
39 | func testVarArray() {
40 | let varArray = VarSignature(string: " var name: [String]?")
41 | XCTAssertEqual(varArray, VarSignature(declaration: "var", name: "name", type: "[String]?"))
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Generate.../GenerateAfterVarCommand.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GenerateAfterVarCommand.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 30/03/2017.
6 | // Copyright © 2017 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | protocol GenerateAfterVarCommand: SelectableGeneratorCommand {
13 |
14 | }
15 |
16 | extension GenerateAfterVarCommand {
17 | func generateForAllVariables(with invocation: XCSourceEditorCommandInvocation) throws {
18 | addLinesAfterVariables(invocation: invocation, lines: try generator(with: invocation).lines)
19 | }
20 |
21 | func generateForSelectedVariables(with invocation: XCSourceEditorCommandInvocation, selections: [XCSourceTextRange]) throws {
22 | addLinesAfterVariables(invocation: invocation, lines: try generator(with: invocation, selections: selections).lines)
23 | }
24 |
25 | private func addLinesAfterVariables(invocation: XCSourceEditorCommandInvocation, lines: [String]) {
26 | var lastVarIndex = 0
27 | var varStarted = false
28 | for l in invocation.buffer.lines {
29 | let line = l as! String
30 | if line.isVar {
31 | varStarted = true
32 | }
33 | if varStarted && !line.isVar {
34 | break
35 | }
36 | lastVarIndex += 1
37 | }
38 | invocation.buffer.lines.insert(lines, at: IndexSet(integersIn: lastVarIndex ..< lastVarIndex+lines.count))
39 | }
40 | }
41 |
42 | private extension String {
43 | var isVar: Bool {
44 | return self.contains("var") || self.contains("let")
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Generate.../String+regexr.swift:
--------------------------------------------------------------------------------
1 | //
2 | // String+regexr.swift
3 | // MockGenerator
4 | //
5 | // Created by WANG Jie on 11/10/2016.
6 | // Copyright © 2016 jwang123. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension String {
12 | func matches(in string: String) -> [NSTextCheckingResult] {
13 | let regex = try! NSRegularExpression(pattern: self)
14 | return regex.matches(in: string, options: [], range: NSRange(0 ..< string.count))
15 | }
16 |
17 | func firstMatch(in string: String) -> NSTextCheckingResult? {
18 | let regex = try! NSRegularExpression(pattern: self)
19 | return regex.firstMatch(in: string, options: [], range: NSRange(0 ..< string.count))
20 | }
21 |
22 | func substring(with range: NSRange) -> String {
23 | return (self as NSString).substring(with: range)
24 | }
25 |
26 | var spaceRemoved: String {
27 | return replacingOccurrences(of: " ", with: "")
28 | }
29 |
30 | /// remove the space at the begining and at the end
31 | var trimed: String {
32 | guard let result = "\\S.*\\S".firstMatch(in: self) else {
33 | return ""
34 | }
35 | return substring(with: result.range)
36 | }
37 |
38 | func count(of char: Character) -> Int {
39 | var count = 0
40 | forEach { c in
41 | if c == char {
42 | count += 1
43 | }
44 | }
45 | return count
46 | }
47 |
48 | func repeating(_ count: Int) -> String {
49 | return Array(repeating: self, count: count).joined()
50 | }
51 |
52 | /// Capitalized the first letter
53 | var Capitalized: String {
54 | return prefix(1).uppercased() + dropFirst()
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/interface1Mock.txt:
--------------------------------------------------------------------------------
1 | class PokemonMock: Pokemon {
2 | var height: Double!
3 | var canEvolve: Bool!
4 |
5 | var eatFood: String?
6 | var drinkWater: String?
7 | var evolveShouldCallSuccessHandler = true
8 | var evolveSuccessHandlerParam0: String!
9 | var evolveShouldCallFailureHandler = true
10 | var evolveFailureHandlerParam0: String!
11 | var evolveFailureHandlerDidReturn: String?
12 |
13 | var eatFoodWasCalled: Bool?
14 | var drinkWasCalled: Bool?
15 | var isFlyingWasCalled: Bool?
16 | var evolveSuccessHandlerWasCalled: Bool?
17 |
18 | var eatFoodWasCalledTimes = 0
19 | var drinkWasCalledTimes = 0
20 | var isFlyingWasCalledTimes = 0
21 | var evolveSuccessHandlerWasCalledTimes = 0
22 |
23 | var isFlyingShouldReturn: Bool!
24 |
25 | func eat(food: String) {
26 | eatFood = food
27 | eatFoodWasCalled = true
28 | eatFoodWasCalledTimes += 1
29 | }
30 |
31 | func drink(_ water: String) {
32 | drinkWater = water
33 | drinkWasCalled = true
34 | drinkWasCalledTimes += 1
35 | }
36 |
37 | func isFlying() -> Bool {
38 | isFlyingWasCalled = true
39 | isFlyingWasCalledTimes += 1
40 | return isFlyingShouldReturn
41 | }
42 |
43 | func evolve(successHandler: @escaping (String) -> Void, failureHandler: (String?) -> String?) {
44 | if evolveShouldCallSuccessHandler {
45 | successHandler(evolveSuccessHandlerParam0)
46 | }
47 | if evolveShouldCallFailureHandler {
48 | evolveFailureHandlerDidReturn = failureHandler(evolveFailureHandlerParam0)
49 | }
50 | evolveSuccessHandlerWasCalled = true
51 | evolveSuccessHandlerWasCalledTimes += 1
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/Generate.../InitGenerator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InitGenerator.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 30/03/2017.
6 | // Copyright © 2017 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct InitGenerator: Generator {
12 | let varSignatures: [VarSignature]
13 | let indentation: String
14 | let interfaceDefinition: InterfaceDefinition
15 |
16 | var interfaceName: String {
17 | return interfaceDefinition.name
18 | }
19 |
20 | init(interfaceSignature: InterfaceSignature, indentation: String) {
21 | self.varSignatures = interfaceSignature.varSignatures
22 | self.interfaceDefinition = interfaceSignature.definition
23 | self.indentation = indentation
24 | }
25 |
26 | init(interfaceDefinition: InterfaceDefinition, varSignatures: [VarSignature], indentation: String) {
27 | self.varSignatures = varSignatures
28 | self.interfaceDefinition = interfaceDefinition
29 | self.indentation = indentation
30 | }
31 |
32 | var lines: [String] {
33 | var lines = [String]()
34 | lines.append("")
35 | var initParams = [String]()
36 | for varSignature in varSignatures {
37 | var type = varSignature.type.name
38 | if varSignature.type.isOptional {
39 | type = varSignature.type.optionalName
40 | }
41 | initParams.append("\(varSignature.name): \(type)")
42 | }
43 | lines.append("\(indentation)init(\(initParams.joined(separator: ", "))) {")
44 | for varSignature in varSignatures {
45 | lines.append("\(indentation.repeating(2))self.\(varSignature.name) = \(varSignature.name)")
46 | }
47 | lines.append("\(indentation)}")
48 | return lines
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Generate.../EquatableGenerator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EquatableGenerator.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 27/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct EquatableGenerator: Generator {
12 | let varSignatures: [VarSignature]
13 | let indentation: String
14 | let interfaceDefinition: InterfaceDefinition
15 |
16 | var interfaceName: String {
17 | return interfaceDefinition.name
18 | }
19 |
20 | init(interfaceSignature: InterfaceSignature, indentation: String) {
21 | self.varSignatures = interfaceSignature.varSignatures
22 | self.interfaceDefinition = interfaceSignature.definition
23 | self.indentation = indentation
24 | }
25 |
26 | init(interfaceDefinition: InterfaceDefinition, varSignatures: [VarSignature], indentation: String) {
27 | self.varSignatures = varSignatures
28 | self.interfaceDefinition = interfaceDefinition
29 | self.indentation = indentation
30 | }
31 |
32 | var lines: [String] {
33 | var lines = [String]()
34 | lines.append("")
35 | lines.append("extension \(interfaceName): Equatable {")
36 | lines.append(contentsOf: equatableLines)
37 | lines.append("}")
38 | return lines
39 | }
40 |
41 | var equatableLines: [String] {
42 | var lines = [String]()
43 | lines.append("\(indentation)static func ==(lhs: \(interfaceName), rhs: \(interfaceName)) -> Bool {")
44 | var varsEquals = [String]()
45 | varSignatures.forEach { varSignature in
46 | varsEquals.append("lhs.\(varSignature.name) == rhs.\(varSignature.name)")
47 | }
48 | lines.append("\(indentation)\(indentation)return \(varsEquals.joined(separator: " && "))")
49 | lines.append("\(indentation)}")
50 | return lines
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Generate.../FuncParam.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FuncParam.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | private let wrongParamFormat = "params format incorrect"
11 |
12 | struct FuncParam {
13 | let label: String
14 | let name: String
15 | let type: SwiftType
16 |
17 | var readableLabel: String {
18 | if label == "_" {
19 | return ""
20 | }
21 | return label
22 | }
23 |
24 | init(string: String) throws {
25 | let comps = string.components(separatedBy: ":")
26 | guard comps.count == 2 else {
27 | throw NSError.sourceInvalid
28 | }
29 | type = TypeParser.parse(string: comps[1].trimed)
30 |
31 | let labelNameComps = comps[0].components(separatedBy: " ").map { $0.spaceRemoved }.filter { !$0.isEmpty }
32 | if labelNameComps.count == 1 {
33 | label = labelNameComps[0]
34 | name = labelNameComps[0]
35 | return
36 | }
37 | if labelNameComps.count == 2 {
38 | let label = labelNameComps[0]
39 | self.label = label
40 | name = labelNameComps[1]
41 | return
42 | }
43 | throw NSError.sourceInvalid
44 | }
45 |
46 | init(label: String, name: String, type: String) {
47 | self.label = label
48 | self.name = name
49 | self.type = TypeParser.parse(string: type)
50 | }
51 | }
52 |
53 | extension FuncParam: Equatable {
54 | static func ==(l: FuncParam, r: FuncParam) -> Bool {
55 | return l.label == r.label && l.name == r.name && l.type == r.type
56 | }
57 | }
58 |
59 | extension FuncParam {
60 | var rawString: String {
61 | let rawString = "\(name): \(type.rawString)"
62 | if name == label {
63 | return rawString
64 | }
65 | return "\(label) \(rawString)"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Generate.../InterfaceSignature.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InterfaceSignature.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct InterfaceSignature {
12 | let interfaceSource: String
13 | let lines: [String]
14 |
15 | var definition: InterfaceDefinition
16 | var funcSignatures: [FuncSignature] = []
17 | var varSignatures: [VarSignature] = []
18 |
19 | init(interfaceSource: String, lines: [String]) throws {
20 | self.interfaceSource = interfaceSource
21 | self.lines = lines
22 | definition = try InterfaceDefinition(lines: lines)
23 | try initFuncSignatures()
24 | initVarSignatures()
25 | }
26 |
27 | mutating func initFuncSignatures() throws {
28 | var funcSignatures: [String] = []
29 | for line in lines {
30 | guard let _ = "func .*?\\(".firstMatch(in: line) else { continue }
31 | let funcSignature = line.replacingOccurrences(of: "{", with: "").replacingOccurrences(of: "\n", with: "")
32 | funcSignatures.append(funcSignature)
33 | }
34 | self.funcSignatures = try funcSignatures.map { try FuncSignature(string: $0) }
35 | }
36 |
37 | mutating func initVarSignatures() {
38 | var openBraceCount = 0
39 | var varSignatures: [VarSignature] = []
40 | for line in lines {
41 | if line.trimed.prefix(2) == "//" {
42 | continue
43 | }
44 | let lineOpen = line.filter { $0 == "{" }
45 | openBraceCount += lineOpen.count
46 | let lineClose = line.filter { $0 == "}" }
47 | openBraceCount -= lineClose.count
48 | guard openBraceCount == 1 else { continue }
49 | guard let varSignature = VarSignature(string: line) else { continue }
50 | varSignatures.append(varSignature)
51 | }
52 | self.varSignatures = varSignatures
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/InterfaceSignatureTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InterfaceSignatureTests.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CodeGenerator
11 |
12 | class InterfaceSignatureTests: XCTestCase {
13 |
14 | var interfaceSignature: InterfaceSignature!
15 |
16 | override func setUp() {
17 | super.setUp()
18 | let source = "//TestClass.swift|import xxx| var global: String|class TestClass{| var var1: String| static var var2: String| private var var3: String| let var4: String?| func func1(param1: String) {\n|xxxx|var funcVar: String| } | func func2(param2: Bool) -> Bool {| return false|}"
19 | interfaceSignature = try! InterfaceSignature(interfaceSource: source, lines: source.components(separatedBy: "|"))
20 | }
21 |
22 | override func tearDown() {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | super.tearDown()
25 | }
26 |
27 | func testInterfaceDefinition() {
28 | XCTAssertEqual(interfaceSignature.definition, try! InterfaceDefinition(lines: interfaceSignature.lines))
29 | }
30 |
31 | func testSourceFuncsSignatures() {
32 | XCTAssertEqual(interfaceSignature.funcSignatures, ["func func1(param1: String) ", "func func2(param2: Bool) -> Bool "].map { try! FuncSignature(string: $0) })
33 | }
34 |
35 | func testVarSignatures() {
36 | let vars = [" var var1: String", " private var var3: String", " let var4: String?"].map { VarSignature(string: $0)! }
37 | XCTAssertEqual(interfaceSignature.varSignatures.count, vars.count)
38 | for i in 0.. String {
14 | return "(\(unwrappedName))\(wrap)"
15 | }
16 |
17 | override var name: String {
18 | return rawString.replacingOccurrences(of: "@escaping", with: "").replacingOccurrences(of: "@autoclosure", with: "").trimed
19 | }
20 |
21 | override var unwrappedName: String {
22 | if isOptional {
23 | let result = "^\\((.*)\\)[?!]$".firstMatch(in: name)!
24 | return name.substring(with: result.range(at: 1))
25 | }
26 | return name
27 | }
28 |
29 | override var isSensible: Bool {
30 | return false
31 | }
32 |
33 | override var isOptional: Bool {
34 | guard name.count > 7 else { return false }
35 | let comps = name.components(separatedBy: "->")
36 | guard comps.count == 2 else { return false }
37 | let leftParenthesesCount = comps[1].count(of: "(")
38 | let rightParentesescount = comps[1].count(of: ")")
39 | let lastTwo = name.suffix(2)
40 | return [")?", ")!"].contains(lastTwo) && leftParenthesesCount != rightParentesescount
41 | }
42 |
43 | var inTypes: [SwiftType] {
44 | let rawInTypes = unwrappedName.components(separatedBy: "->")[0]
45 | guard let result = "\\((.*)\\)".firstMatch(in: rawInTypes) else { return [] }
46 | let inTypesString = rawInTypes.substring(with: result.range(at: 1))
47 | if inTypesString.isEmpty {
48 | return []
49 | }
50 | return inTypesString.components(separatedBy: ",").map { TypeParser.parse(string: $0) }
51 | }
52 |
53 | var outType: SwiftType {
54 | let rawOutType = unwrappedName.components(separatedBy: "->")[1]
55 | return TypeParser.parse(string: rawOutType)
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Generate.../ClosureParamMocker.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ClosureParamMocker.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 28/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct ClosureParamMocker: ParamMocker {
12 |
13 | let param: FuncParam
14 | let funcName: String
15 | let indentation: String
16 |
17 | var closureType: ClosureType {
18 | return param.type as! ClosureType
19 | }
20 |
21 | var variables: [VarSignature] {
22 | var variables = [VarSignature]()
23 | variables.append(varShouldCallClosure)
24 | variables.append(contentsOf: varsIn)
25 | if let varOut = varOut {
26 | variables.append(varOut)
27 | }
28 | return variables
29 | }
30 |
31 | private var varShouldCallClosure: VarSignature {
32 | var varSignature = VarSignature(declaration: "var", name: "\(funcName)ShouldCall\(param.name.Capitalized)", type: TypeParser.parse(string: "Bool?"))
33 | varSignature.initValue = "true"
34 | return varSignature
35 | }
36 |
37 | private var varsIn: [VarSignature] {
38 | var varsIn = [VarSignature]()
39 | closureType.inTypes.enumerated().forEach { index, inType in
40 | varsIn.append(VarSignature(declaration: "var", name: "\(funcName)\(param.name.Capitalized)Param\(index)", type: inType.forceUnwrappedName))
41 | }
42 | return varsIn
43 | }
44 |
45 | private var varOut: VarSignature? {
46 | if closureType.outType == .Void {
47 | return nil
48 | }
49 | return VarSignature(declaration: "var", name: "\(funcName)\(param.name.Capitalized)DidReturn", type: TypeParser.parse(string: closureType.outType.optionalName))
50 | }
51 |
52 | var lines: [String] {
53 | var lines = [String]()
54 | lines.append("\(indentation.repeating(2))if \(varShouldCallClosure.name) {")
55 | let callClosure = "\(param.name)("+varsIn.map { $0.name }.joined(separator: ", ")+")"
56 | if let varOut = varOut {
57 | lines.append("\(indentation.repeating(3))\(varOut.name) = \(callClosure)")
58 | } else {
59 | lines.append("\(indentation.repeating(3))\(callClosure)")
60 | }
61 | lines.append("\(indentation.repeating(2))}")
62 | return lines
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Generate.../FuncMocker.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FuncMocker.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct FuncMocker {
12 | var paramMockers: [ParamMocker] = []
13 | let funcSignature: FuncSignature
14 | let indentation: String
15 |
16 | init(funcSignature: FuncSignature, indentationWidth: Int) {
17 | let indentation = " ".repeating(indentationWidth)
18 | self.funcSignature = funcSignature
19 | paramMockers = funcSignature.params.map { ParamMockerFactory.create(funcParam: $0, funcName: funcSignature.name, indentation: indentation) }
20 | self.indentation = indentation
21 | }
22 |
23 | var sensibleVariables: [VarSignature] {
24 | return paramMockers.flatMap { $0.variables }
25 | }
26 |
27 | var wasCalledVariable: VarSignature {
28 | return VarSignature(declaration: "var", name: funcSignature.readableName + "WasCalled", type: "Bool?")
29 | }
30 |
31 | var wasCalledTimesVariable: VarSignature {
32 | var varSignature = VarSignature(declaration: "var", name: funcSignature.readableName + "WasCalledTimes", type: "Int")
33 | varSignature.initValue = "0"
34 | return varSignature
35 | }
36 |
37 | var returnVariable: VarSignature? {
38 | if funcSignature.isReturnVoid {
39 | return nil
40 | }
41 | return VarSignature(declaration: "var", name: funcSignature.readableName + "ShouldReturn", type: funcSignature.returnType.forceUnwrappedName)
42 | }
43 |
44 | var bodyLines: [String] {
45 | var bodyLines = paramMockers.flatMap { $0.lines }
46 | let wasCalledBodyLine = "\(indentation)\(indentation)\(wasCalledVariable.name) = true"
47 | bodyLines.append(wasCalledBodyLine)
48 | let wasCalledTimesBodyLine = "\(indentation)\(indentation)\(wasCalledTimesVariable.name) += 1"
49 | bodyLines.append(wasCalledTimesBodyLine)
50 | if let returnVariable = returnVariable {
51 | let returnLine = "\(indentation)\(indentation)return \(returnVariable.name)"
52 | bodyLines.append(returnLine)
53 | }
54 | return bodyLines
55 | }
56 |
57 | var lines: [String] {
58 | var lines: [String] = []
59 | lines.append("\(indentation)\(funcSignature.rawString) {")
60 | lines.append(contentsOf: bodyLines)
61 | lines.append("\(indentation)}")
62 | return lines
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Generate.../InterfaceMocker.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InterfaceMocker.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct InterfaceMocker {
12 | let interfaceSignature: InterfaceSignature
13 | let variables: [VarSignature]
14 | let sensibleVariables: [VarSignature]
15 | let wasCalledVariables: [VarSignature]
16 | let wasCalledVariablesTimes: [VarSignature]
17 | let returnVariables: [VarSignature]
18 | let funcsMockers: [FuncMocker]
19 | let indentation: String
20 |
21 | private var interfaceName: String {
22 | return interfaceSignature.definition.name
23 | }
24 |
25 | init(interfaceSignature: InterfaceSignature, indentationWidth: Int) {
26 | indentation = " ".repeating(indentationWidth)
27 | self.interfaceSignature = interfaceSignature
28 | variables = interfaceSignature.varSignatures.filter { !$0.isPrivate }
29 | funcsMockers = interfaceSignature.funcSignatures.map { FuncMocker(funcSignature: $0, indentationWidth: indentationWidth) }
30 | sensibleVariables = funcsMockers.flatMap { $0.sensibleVariables }
31 | wasCalledVariables = funcsMockers.map { $0.wasCalledVariable }
32 | wasCalledVariablesTimes = funcsMockers.map { $0.wasCalledTimesVariable }
33 | returnVariables = funcsMockers.flatMap { $0.returnVariable }
34 | }
35 |
36 | var lines: [String] {
37 | var lines = [String]()
38 | lines.append("class \(interfaceName)Mock: \(interfaceName) {")
39 | lines += linesOf(variables: variables, varType: { $0.rawType })
40 | lines += linesOf(variables: sensibleVariables, varType: { $0.rawType })
41 | lines += linesOf(variables: wasCalledVariables, varType: { $0.optionalType })
42 | lines += linesOf(variables: wasCalledVariablesTimes, varType: { $0.rawType })
43 | lines += linesOf(variables: returnVariables, varType: { $0.forceUnwrappedType })
44 | funcsMockers.forEach { funcMocker in
45 | lines.append(contentsOf: funcMocker.lines)
46 | lines.append("")
47 | }
48 | lines.append("}")
49 | return lines
50 | }
51 |
52 | private func linesOf(variables: [VarSignature], varType: (VarSignature) -> String) -> [String] {
53 | guard !variables.isEmpty else { return [] }
54 | var lines = [String]()
55 | variables.forEach { lines.append("\(indentation)\(varType($0))") }
56 | lines.append("")
57 | return lines
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Generate.../HashableGenerator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HashableGenerator.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 02/01/2017.
6 | // Copyright © 2017 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct HashableGenerator: Generator {
12 | var equatableGenerator: EquatableGenerator
13 |
14 | var interfaceName: String {
15 | return equatableGenerator.interfaceDefinition.name
16 | }
17 |
18 | var indentation: String {
19 | return equatableGenerator.indentation
20 | }
21 |
22 | var varSignatures: [VarSignature] {
23 | return equatableGenerator.varSignatures
24 | }
25 |
26 | init(interfaceSignature: InterfaceSignature, indentation: String) {
27 | self.equatableGenerator = EquatableGenerator(interfaceSignature: interfaceSignature, indentation: indentation)
28 | }
29 |
30 | init(interfaceDefinition: InterfaceDefinition, varSignatures: [VarSignature], indentation: String) {
31 | self.equatableGenerator = EquatableGenerator(interfaceDefinition: interfaceDefinition, varSignatures: varSignatures, indentation: indentation)
32 | }
33 |
34 | var lines: [String] {
35 | var lines = [String]()
36 | lines.append("")
37 | lines.append("extension \(interfaceName): Hashable {")
38 | lines.append(contentsOf: equatableGenerator.equatableLines)
39 | lines.append("")
40 | lines.append(contentsOf: hashValueLines)
41 | lines.append("}")
42 | return lines
43 | }
44 |
45 | var hashValueLines: [String] {
46 | var lines = [String]()
47 | lines.append("\(indentation)var hashValue: Int {")
48 | lines.append("\(indentation)\(indentation)var hashValue = 1")
49 | let hashableVars = varSignatures.map { $0.name }.joined(separator: ", ")
50 | var varsType = "[AnyHashable]"
51 | var varHash = "$0.hashValue"
52 | if (varSignatures.filter { $0.type.isOptional }).count > 0 {
53 | varsType = "[AnyHashable?]"
54 | varHash = "($0?.hashValue ?? 0)"
55 | }
56 | lines.append("\(indentation)\(indentation)let hashableVars: \(varsType) = [\(hashableVars)]")
57 |
58 | lines.append("\(indentation)\(indentation)hashableVars.forEach {")
59 | lines.append("\(indentation)\(indentation)\(indentation)hashValue = 31 * hashValue + \(varHash)")
60 | lines.append("\(indentation)\(indentation)}")
61 | lines.append("\(indentation)\(indentation)return hashValue")
62 | lines.append("\(indentation)}")
63 | return lines
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Generate.../VarSignature.swift:
--------------------------------------------------------------------------------
1 | //
2 | // VarSignature.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct VarSignature {
12 |
13 | /// `let` or `var`
14 | let declaration: String
15 | let name: String
16 | let type: SwiftType
17 | var accessLevel: AccessLevel = .internal
18 | var initValue: String?
19 |
20 | init?(string: String) {
21 | guard let _ = "^(?!.*static).*\\s(let|var) \\S".firstMatch(in: string) else {
22 | return nil
23 | }
24 | guard let result = "(var|let)\\s*(\\S*)\\s*:\\s*(\\S[^\\{]*[^ \\{])".firstMatch(in: string) else {
25 | return nil
26 | }
27 | declaration = string.substring(with: result.range(at: 1))
28 | name = string.substring(with: result.range(at: 2))
29 | let typeString = string.substring(with: result.range(at: 3))
30 | type = TypeParser.parse(string: typeString)
31 | accessLevel = AccessLevel(string: string)
32 | }
33 |
34 | init(declaration: String, name: String, type: SwiftType, accessLevel: AccessLevel = .internal) {
35 | self.declaration = declaration
36 | self.name = name
37 | self.type = type
38 | self.accessLevel = accessLevel
39 | }
40 |
41 | init(declaration: String, name: String, type: String, accessLevel: AccessLevel = .internal) {
42 | self.declaration = declaration
43 | self.name = name
44 | self.type = TypeParser.parse(string: type)
45 | self.accessLevel = accessLevel
46 | }
47 |
48 | var isPrivate: Bool {
49 | return accessLevel.isPrivate
50 | }
51 | }
52 |
53 | extension VarSignature: Equatable {
54 | static func ==(l: VarSignature, r: VarSignature) -> Bool {
55 | return l.declaration == r.declaration && l.name == r.name && l.type == r.type && l.accessLevel == r.accessLevel
56 | }
57 | }
58 |
59 |
60 |
61 | extension VarSignature {
62 | var rawType: String {
63 | return string(with: type.name)
64 | }
65 |
66 | var unwrappedType: String {
67 | return string(with: type.unwrappedName)
68 | }
69 |
70 | var optionalType: String {
71 | return string(with: type.optionalName)
72 | }
73 |
74 | var forceUnwrappedType: String {
75 | return string(with: type.forceUnwrappedName)
76 | }
77 |
78 | private func string(with type: String) -> String {
79 | if let initValue = initValue {
80 | return "\(declaration) \(name) = \(initValue)"
81 | }
82 | return "\(declaration) \(name): \(type)"
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/FuncSignatureTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FuncSignatureTests.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CodeGenerator
11 |
12 | class FuncSignatureTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | }
17 |
18 | override func tearDown() {
19 | // Put teardown code here. This method is called after the invocation of each test method in the class.
20 | super.tearDown()
21 | }
22 |
23 | func testFunc1() {
24 | let func1 = try! FuncSignature(string: "func func1(param1: String, param2Label param2: Bool, closureLabel closure: (String) -> Bool) -> Bool {")
25 | XCTAssertEqual(func1.name, "func1")
26 | XCTAssertEqual(func1.returnType, TypeParser.parse(string: "Bool"))
27 | XCTAssertEqual(func1.params.count, 3)
28 | XCTAssertEqual(func1.params[0], FuncParam(label: "param1", name: "param1", type: "String"))
29 | XCTAssertEqual(func1.params[1], FuncParam(label: "param2Label", name: "param2", type: "Bool"))
30 | XCTAssertEqual(func1.params[2], FuncParam(label: "closureLabel", name: "closure", type: "(String) -> Bool"))
31 | }
32 |
33 | func testFunc2() {
34 | let func2 = try! FuncSignature(string: "func func2(closure: (String?) -> Int?, closure2Label closure2: @escaping (String?) -> String?) -> String? {")
35 | XCTAssertEqual(func2.name, "func2")
36 | XCTAssertEqual(func2.returnType, TypeParser.parse(string: "String?"))
37 | XCTAssertEqual(func2.params.count, 2)
38 | XCTAssertEqual(func2.params[0], FuncParam(label: "closure", name: "closure", type: "(String?) -> Int?"))
39 | XCTAssertEqual(func2.params[1], FuncParam(label: "closure2Label", name: "closure2", type: "@escaping (String?) -> String?"))
40 | XCTAssertEqual(func2.rawString, "func func2(closure: (String?) -> Int?, closure2Label closure2: @escaping (String?) -> String?) -> String?")
41 | }
42 |
43 | func testFunc3() {
44 | let func3 = try! FuncSignature(string: "func func3(_ param: String)")
45 | XCTAssertEqual(func3.name, "func3")
46 | XCTAssertEqual(func3.returnType, SwiftType.Void)
47 | XCTAssertEqual(func3.params.count, 1)
48 | XCTAssertEqual(func3.params[0], FuncParam(label: "_", name: "param", type: "String"))
49 | }
50 |
51 | func testFunc4() {
52 | let func4 = try! FuncSignature(string: "func func4() {")
53 | XCTAssertEqual(func4.name, "func4")
54 | XCTAssertEqual(func4.returnType, SwiftType.Void)
55 | XCTAssertEqual(func4.params.count, 0)
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/FuncMockTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FuncMockerTests.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CodeGenerator
11 |
12 | class FuncMockerTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | }
17 |
18 | override func tearDown() {
19 | // Put teardown code here. This method is called after the invocation of each test method in the class.
20 | super.tearDown()
21 | }
22 |
23 | func testFunMock() {
24 | let funcSignature = try! FuncSignature(string: "func test(funcMock: String, successHandler: @escaping (String, Int?) -> String?) -> String {")
25 | let funcMocker = FuncMocker(funcSignature: funcSignature, indentationWidth: 1)
26 | XCTAssertEqual(funcMocker.sensibleVariables.count, 5)
27 | XCTAssertEqual(funcMocker.sensibleVariables[0], VarSignature(string: " var testFuncMock: String?"))
28 |
29 | XCTAssertEqual(funcMocker.sensibleVariables[1], VarSignature(string: " var testShouldCallSuccessHandler: Bool?"))
30 | XCTAssertEqual(funcMocker.sensibleVariables[2], VarSignature(string: " var testSuccessHandlerParam0: String!"))
31 | XCTAssertEqual(funcMocker.sensibleVariables[3], VarSignature(string: " var testSuccessHandlerParam1: Int!"))
32 | XCTAssertEqual(funcMocker.sensibleVariables[4], VarSignature(string: " var testSuccessHandlerDidReturn: String?"))
33 | XCTAssertEqual(funcMocker.wasCalledVariable, VarSignature(string: " var testFuncMockWasCalled: Bool?"))
34 | var wasCalledTimesVar = VarSignature(declaration: "var", name: "testFuncMockWasCalledTimes", type: "Int", accessLevel: .internal)
35 | wasCalledTimesVar.initValue = "0"
36 | XCTAssertEqual(funcMocker.wasCalledTimesVariable, wasCalledTimesVar)
37 | XCTAssertEqual(funcMocker.returnVariable, VarSignature(string: " var testFuncMockShouldReturn: String!"))
38 |
39 | var expectedBodyLines = string(from: "funcMock", ofType: "txt").components(separatedBy: "\n")
40 | expectedBodyLines.removeLast()
41 | XCTAssertEqual(funcMocker.bodyLines.count, expectedBodyLines.count)
42 | for i in 0.. String?)")
49 | let funcMocker = FuncMocker(funcSignature: funcSignature, indentationWidth: 1)
50 | XCTAssertNil(funcMocker.returnVariable)
51 | }
52 |
53 | func testFuncMocker1() {
54 | let funcSignature = try! FuncSignature(string: "func func3() {")
55 | let funcMocker = FuncMocker(funcSignature: funcSignature, indentationWidth: 1)
56 | XCTAssertEqual(funcMocker.sensibleVariables.count, 0)
57 | XCTAssertEqual(funcMocker.wasCalledVariable, VarSignature(declaration: "var", name: "func3WasCalled", type: "Bool?"))
58 | XCTAssertNil(funcMocker.returnVariable)
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Generate.../Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | Generate...
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | XPC!
19 | CFBundleShortVersionString
20 | 0.04
21 | CFBundleVersion
22 | 4
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSExtension
26 |
27 | NSExtensionAttributes
28 |
29 | XCSourceEditorCommandDefinitions
30 |
31 |
32 | XCSourceEditorCommandClassName
33 | $(PRODUCT_MODULE_NAME).GenerateMockCommand
34 | XCSourceEditorCommandIdentifier
35 | $(PRODUCT_BUNDLE_IDENTIFIER).GenerateMockCommand
36 | XCSourceEditorCommandName
37 | Mock
38 |
39 |
40 | XCSourceEditorCommandClassName
41 | $(PRODUCT_MODULE_NAME).GenerateEquatableCommand
42 | XCSourceEditorCommandIdentifier
43 | $(PRODUCT_BUNDLE_IDENTIFIER).GenerateEquatableCommand
44 | XCSourceEditorCommandName
45 | Equatable
46 |
47 |
48 | XCSourceEditorCommandClassName
49 | $(PRODUCT_MODULE_NAME).GenerateHashableCommand
50 | XCSourceEditorCommandIdentifier
51 | $(PRODUCT_BUNDLE_IDENTIFIER).GenerateHashableCommand
52 | XCSourceEditorCommandName
53 | Hashable
54 |
55 |
56 | XCSourceEditorCommandClassName
57 | $(PRODUCT_MODULE_NAME).GenerateInitCommand
58 | XCSourceEditorCommandIdentifier
59 | $(PRODUCT_BUNDLE_IDENTIFIER).GenerateInitCommand
60 | XCSourceEditorCommandName
61 | Init
62 |
63 |
64 | XCSourceEditorCommandClassName
65 | $(PRODUCT_MODULE_NAME).GenerateCodingCommand
66 | XCSourceEditorCommandIdentifier
67 | $(PRODUCT_BUNDLE_IDENTIFIER).GenerateCodingCommand
68 | XCSourceEditorCommandName
69 | NSCoding
70 |
71 |
72 | XCSourceEditorExtensionPrincipalClass
73 | $(PRODUCT_MODULE_NAME).SourceEditorExtension
74 |
75 | NSExtensionPointIdentifier
76 | com.apple.dt.Xcode.extension.source-editor
77 |
78 | NSHumanReadableCopyright
79 | Copyright © 2016 wangjie. All rights reserved.
80 |
81 |
82 |
--------------------------------------------------------------------------------
/Generate.../SelectableGeneratorCommand.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SelectableGeneratorCommand.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 02/01/2017.
6 | // Copyright © 2017 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XcodeKit
11 |
12 | protocol SelectableGeneratorCommand: XCSourceEditorCommand {
13 |
14 | var generatorType: Generator.Type { get }
15 |
16 | func generator(with invocation: XCSourceEditorCommandInvocation, selections: [XCSourceTextRange]) throws -> Generator
17 |
18 | func generator(with invocation: XCSourceEditorCommandInvocation) throws -> Generator
19 |
20 | func swiftPerform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void)
21 |
22 | func generateForAllVariables(with invocation: XCSourceEditorCommandInvocation) throws
23 |
24 | func generateForSelectedVariables(with invocation: XCSourceEditorCommandInvocation, selections: [XCSourceTextRange]) throws
25 | }
26 |
27 | extension SelectableGeneratorCommand where Self: NSObject {
28 | func swiftPerform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void) {
29 | var selections = invocation.buffer.selections.map { $0 as! XCSourceTextRange }
30 | selections = selections.filter { $0.start != $0.end }
31 | do {
32 | if selections.isEmpty {
33 | try generateForAllVariables(with: invocation)
34 | } else {
35 | try generateForSelectedVariables(with: invocation, selections: selections)
36 | }
37 | completionHandler(nil)
38 | } catch {
39 | completionHandler(error)
40 | }
41 | }
42 |
43 | private func selectedLines(with invocation: XCSourceEditorCommandInvocation, selections: [XCSourceTextRange]) -> [String] {
44 | let selectedColumns = selections.map { $0.start.line...$0.end.line }.flatMap { $0 }
45 | var selectedLines: [String] = []
46 | invocation.buffer.lines.enumerated().forEach { index, line in
47 | if selectedColumns.contains(index) {
48 | selectedLines.append(line as! String)
49 | }
50 | }
51 | return selectedLines
52 | }
53 |
54 | func generator(with invocation: XCSourceEditorCommandInvocation, selections: [XCSourceTextRange]) throws -> Generator {
55 | let selectedVars = selectedLines(with: invocation, selections: selections).flatMap { VarSignature(string: $0) }
56 | return generatorType.init(interfaceDefinition: try interfaceSignature(of: invocation).definition, varSignatures: selectedVars, indentation: " ".repeating(invocation.buffer.indentationWidth))
57 | }
58 |
59 | func generator(with invocation: XCSourceEditorCommandInvocation) throws -> Generator {
60 | return generatorType.init(interfaceSignature: try interfaceSignature(of: invocation), indentation: " ".repeating(invocation.buffer.indentationWidth))
61 | }
62 | }
63 |
64 | extension XCSourceTextPosition: Equatable {
65 | public static func==(l: XCSourceTextPosition, r: XCSourceTextPosition) -> Bool {
66 | return l.column == r.column && r.line == l.line
67 | }
68 | }
69 |
70 | func interfaceSignature(of invocation: XCSourceEditorCommandInvocation) throws -> InterfaceSignature {
71 | return try InterfaceSignature(interfaceSource: invocation.buffer.completeBuffer, lines: invocation.buffer.lines.map { $0 as! String })
72 | }
73 |
--------------------------------------------------------------------------------
/CodeGeneratorTests/SwiftTypeTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftTypeTests.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 26/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CodeGenerator
11 |
12 | class SwiftTypeTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testType1() {
25 | let type1 = TypeParser.parse(string: "Bool")
26 | XCTAssertEqual(type1.name, "Bool")
27 | XCTAssertEqual(type1.unwrappedName, "Bool")
28 | XCTAssertEqual(type1.isOptional, false)
29 | XCTAssertEqual(type1 is ClosureType, false)
30 | XCTAssertEqual(type1.optionalName, "Bool?")
31 | }
32 |
33 | func testType2() {
34 | let type2 = TypeParser.parse(string: "String?")
35 | XCTAssertEqual(type2.name, "String?")
36 | XCTAssertEqual(type2.unwrappedName, "String")
37 | XCTAssertEqual(type2 is ClosureType, false)
38 | XCTAssertEqual(type2.isOptional, true)
39 | XCTAssertEqual(type2.optionalName, "String?")
40 | }
41 |
42 | func testArrayType() {
43 | let arrayType = TypeParser.parse(string: "[String]?")
44 | XCTAssertEqual(arrayType.name, "[String]?")
45 | XCTAssertEqual(arrayType.unwrappedName, "[String]")
46 | XCTAssertEqual(arrayType is ClosureType, false)
47 | XCTAssertTrue(arrayType.isOptional)
48 | }
49 |
50 | func testType3() {
51 | let type3 = TypeParser.parse(string: "@escaping @autoclosure (String?) -> String?")
52 | XCTAssertEqual(type3.name, "(String?) -> String?")
53 | XCTAssertEqual(type3.rawString, "@escaping @autoclosure (String?) -> String?")
54 | XCTAssertEqual(type3.unwrappedName, "(String?) -> String?")
55 | XCTAssertEqual(type3.isOptional, false)
56 | XCTAssertEqual(type3 is ClosureType, true)
57 | XCTAssertEqual(type3.optionalName, "((String?) -> String?)?")
58 | }
59 |
60 | func testType4() {
61 | let type3 = TypeParser.parse(string: "@escaping @autoclosure ((String?) -> String?)?")
62 | XCTAssertEqual(type3.name, "((String?) -> String?)?")
63 | XCTAssertEqual(type3.rawString, "@escaping @autoclosure ((String?) -> String?)?")
64 | XCTAssertEqual(type3.unwrappedName, "(String?) -> String?")
65 | XCTAssertEqual(type3.isOptional, true)
66 | XCTAssertEqual(type3 is ClosureType, true)
67 | XCTAssertEqual(type3.optionalName, "((String?) -> String?)?")
68 | }
69 |
70 | func testClosureType() {
71 | let closureType = ClosureType(rawString: "@escaping @autoclosure ((String?, Int) -> String?)?")
72 | XCTAssertEqual(closureType.inTypes[0], TypeParser.parse(string: "String?"))
73 | XCTAssertEqual(closureType.inTypes[1], TypeParser.parse(string: "Int"))
74 | XCTAssertEqual(closureType.outType, TypeParser.parse(string: "String?"))
75 | }
76 |
77 | func testClosureType1() {
78 | let closureType = ClosureType(rawString: "@escaping @autoclosure (String?, Int) -> String?")
79 | XCTAssertEqual(closureType.inTypes[0], TypeParser.parse(string: "String?"))
80 | XCTAssertEqual(closureType.inTypes[1], TypeParser.parse(string: "Int"))
81 | XCTAssertEqual(closureType.outType, TypeParser.parse(string: "String?"))
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Generate.../CodingGenerator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CodingGenerator.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 23/05/2017.
6 | // Copyright © 2017 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct CodingGenerator: Generator {
12 | let varSignatures: [VarSignature]
13 | let indentation: String
14 | let interfaceDefinition: InterfaceDefinition
15 |
16 | var interfaceName: String {
17 | return interfaceDefinition.name
18 | }
19 |
20 | init(interfaceSignature: InterfaceSignature, indentation: String) {
21 | self.varSignatures = interfaceSignature.varSignatures
22 | self.interfaceDefinition = interfaceSignature.definition
23 | self.indentation = indentation
24 | }
25 |
26 | init(interfaceDefinition: InterfaceDefinition, varSignatures: [VarSignature], indentation: String) {
27 | self.varSignatures = varSignatures
28 | self.interfaceDefinition = interfaceDefinition
29 | self.indentation = indentation
30 | }
31 |
32 | var lines: [String] {
33 | var lines = [String]()
34 | lines.append(contentsOf: decodeLines)
35 | lines.append(contentsOf: encodeLines)
36 | return lines
37 | }
38 |
39 | var encodeLines: [String] {
40 | var lines = [String]()
41 | lines.append("")
42 | lines.append("\(indentation)func encode(with aCoder: NSCoder) {")
43 | for varSignature in varSignatures {
44 | lines.append("\(indentation.repeating(2))aCoder.encode(\(varSignature.name), forKey: \"\(varSignature.name)\")")
45 | }
46 | lines.append("\(indentation)}")
47 | return lines
48 | }
49 |
50 | var decodeLines: [String] {
51 |
52 | var lines = [String]()
53 | lines.append("")
54 | lines.append("\(indentation)required init?(coder aDecoder: NSCoder) {")
55 | var guards = "guard "
56 | varSignatures.filter { $0.shouldGuard }.forEach { varSignature in
57 | let guardVar = "let \(varSignature.name) = aDecoder.\(varSignature.decodeName), "
58 | guards.append(guardVar)
59 | }
60 | guards.removeSubrange(Range(uncheckedBounds: (lower: guards.index(guards.endIndex, offsetBy: -2), upper: guards.endIndex)))
61 | guards.append(" else { return nil }")
62 | lines.append(indentation.repeating(2) + guards)
63 | for varSignature in varSignatures {
64 | if varSignature.shouldGuard {
65 | lines.append(indentation.repeating(2) + "self.\(varSignature.name) = \(varSignature.name)")
66 | continue
67 | }
68 | if varSignature.type.isOptional {
69 | lines.append(indentation.repeating(2) + "if aDecoder.containsValue(forKey: \"\(varSignature.name)\") {")
70 | lines.append(indentation.repeating(3) + "\(varSignature.name) = aDecoder.\(varSignature.decodeName)")
71 | lines.append(indentation.repeating(2) + "}")
72 | continue
73 | }
74 | lines.append(indentation.repeating(2) + "\(varSignature.name) = aDecoder.\(varSignature.decodeName)")
75 |
76 | }
77 | lines.append("\(indentation)}")
78 | return lines
79 | }
80 |
81 | }
82 |
83 | private extension VarSignature {
84 | var shouldGuard: Bool {
85 | return isObject && !type.isOptional
86 | }
87 |
88 | var isObject: Bool {
89 | return decodeName.contains("decodeObject")
90 | }
91 |
92 | var decodeName: String {
93 | let types = ["Bool": "decodeBool", "Int32": "decodeInt32", "Int64": "decodeInt64", "Float": "decodeFloat", "Double": "decodeDouble", "TimeInterval": "decodeDouble", "Int": "decodeInteger"]
94 | guard let _ = types.index(forKey: type.unwrappedName) else {
95 | return "decodeObject(forKey: \"\(name)\") as? \(type.unwrappedName)"
96 | }
97 | return "\(types[type.unwrappedName]!)(forKey: \"\(name)\")"
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/CodeGenerator.xcodeproj/xcshareddata/xcschemes/CodeGenerator.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
34 |
40 |
41 |
42 |
43 |
44 |
50 |
51 |
52 |
53 |
54 |
55 |
66 |
70 |
71 |
72 |
78 |
79 |
80 |
81 |
82 |
83 |
89 |
91 |
97 |
98 |
99 |
100 |
102 |
103 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/Generate.../FuncSignature.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FuncSignature.swift
3 | // CodeGenerator
4 | //
5 | // Created by WANG Jie on 25/12/2016.
6 | // Copyright © 2016 wangjie. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | private let wrongFuncFormat = "func format incorrect"
12 |
13 | struct FuncSignature {
14 | let name: String
15 | let params: [FuncParam]
16 | let returnType: SwiftType
17 |
18 | var readableName: String {
19 | if params.isEmpty {
20 | return name
21 | }
22 | return name + params[0].readableLabel.Capitalized
23 | }
24 |
25 | var isReturnVoid: Bool {
26 | return returnType == SwiftType.Void
27 | }
28 |
29 | init(string: String) throws {
30 | guard let nameResult = "func ([\\S]*)\\(".firstMatch(in: string) else {
31 | throw NSError.sourceInvalid
32 | }
33 | name = string.substring(with: nameResult.range(at: 1))
34 |
35 | let paramsRange = try string.paramsRange()
36 | let rawParams = String(string[paramsRange])
37 | let paramsString = rawParams.paramsStrings
38 | params = paramsString.map { paramString in
39 | try? FuncParam(string: paramString.trimed)
40 | }.flatMap { $0 }
41 | let stringAfterLastParam = String(string[paramsRange.upperBound...])
42 |
43 | guard let returnTypeResult = "->(.*)$".firstMatch(in: stringAfterLastParam) else {
44 | returnType = SwiftType.Void
45 | return
46 | }
47 | let returnTypeString = stringAfterLastParam.substring(with: returnTypeResult.range(at: 1)).replacingOccurrences(of: "{", with: "").trimed
48 | returnType = TypeParser.parse(string: returnTypeString)
49 | }
50 | }
51 |
52 | private extension String {
53 | func paramsRange() throws -> Range {
54 | var startParenthesisCount = 0
55 | var endParenthesisCount = 0
56 | var paramsStartIndex: Int!
57 | var paramsEndIndex: Int!
58 | enumerated().forEach { index, char in
59 | if char == "(" {
60 | startParenthesisCount += 1
61 | if paramsStartIndex == nil {
62 | paramsStartIndex = index
63 | }
64 | }
65 | if char == ")" {
66 | endParenthesisCount += 1
67 | }
68 | if startParenthesisCount != 0 && startParenthesisCount == endParenthesisCount {
69 | if paramsEndIndex == nil {
70 | paramsEndIndex = index
71 | }
72 | }
73 | }
74 |
75 | guard var startIntIndex = paramsStartIndex, let endIntIndex = paramsEndIndex else {
76 | throw NSError.sourceInvalid
77 | }
78 | startIntIndex += 1
79 | let startIndex = index(self.startIndex, offsetBy: startIntIndex)
80 | let endIndex = index(self.startIndex, offsetBy: endIntIndex)
81 | return startIndex.. Bool {
110 | return l.name == r.name && l.params == r.params && l.returnType == r.returnType
111 | }
112 | }
113 |
114 | extension FuncSignature {
115 | var rawString: String {
116 | let paramsString = params.map { $0.rawString }.joined(separator: ", ")
117 | let rawString = "func \(name)(\(paramsString))"
118 | if isReturnVoid {
119 | return rawString
120 | }
121 | return "\(rawString) -> \(returnType.name)"
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Installation
2 | 1. Clone or download the repo
3 | 2. Open ``CodeGenerator.xcodeproj``
4 | 3. Enable target signing for both the Application and the Source Code Extension using your own developer ID
5 | 4. Select the application target and then Product > Archive
6 | 5. Export the archive as a macOS App
7 | 6. Run the app, then quit (Don't delete the app, put it in a convenient folder)
8 | 7. Go to System Preferences -> Extensions -> Xcode Source Editor and enable the CodeGenerator extension
9 | 8. The menu-item should now be available from Xcode's Editor menu
10 |
11 | # Uninstallation
12 | 1. Remove the App, restart Xcode.
13 |
14 | # CodeGenerator
15 | CodeGenerator is a Xcode extension for swift code generation.
16 |
17 | 
18 |
19 | ## Generating mock
20 |
21 | ### Example:
22 |
23 | ```swift
24 | protocol Pokemon {
25 | var height: Double! { get set }
26 | var canEvolve: Bool! { get }
27 |
28 | func eat(food: String)
29 |
30 | func drink(_ water: String)
31 |
32 | func isFlying() -> Bool
33 |
34 | func evolve(successHandler: @escaping (String) -> Void, failureHandler: (String?) -> String?)
35 | }
36 | ```
37 |
38 | ```swift
39 | class PokemonMock: Pokemon {
40 | var height: Double!
41 | var canEvolve: Bool!
42 |
43 | var eatFood: String?
44 | var drinkWater: String?
45 | var evolveShouldCallSuccessHandler = true
46 | var evolveSuccessHandlerParam0: String!
47 | var evolveShouldCallFailureHandler = true
48 | var evolveFailureHandlerParam0: String!
49 | var evolveFailureHandlerDidReturn: String?
50 |
51 | var eatFoodWasCalled: Bool?
52 | var drinkWasCalled: Bool?
53 | var isFlyingWasCalled: Bool?
54 | var evolveSuccessHandlerWasCalled: Bool?
55 |
56 | var isFlyingShouldReturn: Bool!
57 |
58 | func eat(food: String) {
59 | eatFood = food
60 | eatFoodWasCalled = true
61 | }
62 |
63 | func drink(_ water: String) {
64 | drinkWater = water
65 | drinkWasCalled = true
66 | }
67 |
68 | func isFlying() -> Bool {
69 | isFlyingWasCalled = true
70 | return isFlyingShouldReturn
71 | }
72 |
73 | func evolve(successHandler: @escaping (String) -> Void, failureHandler: (String?) -> String?) {
74 | if evolveShouldCallSuccessHandler {
75 | successHandler(evolveSuccessHandlerParam0)
76 | }
77 | if evolveShouldCallFailureHandler {
78 | evolveFailureHandlerDidReturn = failureHandler(evolveFailureHandlerParam0)
79 | }
80 | evolveSuccessHandlerWasCalled = true
81 | }
82 |
83 | }
84 | ```
85 |
86 | ## Generating Equatable
87 | ### Example:
88 | ```swift
89 | class EquatableClazz {
90 | var var0: Int!
91 | let var1: String
92 | var var2: Bool?
93 | }
94 | ```
95 |
96 | ```swift
97 | extension EquatableClazz: Equatable {
98 | static func ==(lhs: EquatableClazz, rhs: EquatableClazz) -> Bool {
99 | return lhs.var0 == rhs.var0 && lhs.var1 == rhs.var1 && lhs.var2 == rhs.var2
100 | }
101 | }
102 | ```
103 |
104 | if you don't want to use all the vars for the Equatable, just select the vars you want and click Generate... -> Equatable
105 |
106 | ## Generating Hashable
107 | ### Example:
108 | ```swift
109 | class EquatableClazz {
110 | var var0: Int!
111 | let var1: String
112 | var var2: Bool?
113 | }
114 | ```
115 |
116 | ```swift
117 | extension EquatableClazz: Hashable {
118 | static func ==(lhs: EquatableClazz, rhs: EquatableClazz) -> Bool {
119 | return lhs.var0 == rhs.var0 && lhs.var1 == rhs.var1 && lhs.var2 == rhs.var2
120 | }
121 |
122 | var hashValue: Int {
123 | var hashValue = 1
124 | let hashableVars: [AnyHashable?] = [var0, var1, var2]
125 | hashableVars.forEach {
126 | hashValue = 31 * hashValue + ($0?.hashValue ?? 0)
127 | }
128 | return hashValue
129 | }
130 | }
131 | ```
132 |
133 |
134 | ## Generating Init
135 | ### Example:
136 | ```swift
137 | class EquatableClazz {
138 | var var0: Int!
139 | let var1: String
140 | var var2: Bool?
141 |
142 | init(var0: Int?, var1: String, var2: Bool?) {
143 | self.var0 = var0
144 | self.var1 = var1
145 | self.var2 = var2
146 | }
147 |
148 |
149 | }
150 | ```
151 |
152 | ## Generating NSCoding
153 | ### Example:
154 | ```swift
155 | class EquatableClazz {
156 | var var0: Int
157 | let var1: String
158 | var var2: Bool?
159 |
160 | required init?(coder aDecoder: NSCoder) {
161 | guard let var1 = aDecoder.decodeObject(forKey: "var1") as? String else { return nil }
162 | var0 = aDecoder.decodeInteger(forKey: "var0")
163 | self.var1 = var1
164 | if aDecoder.containsValue(forKey: "var2") {
165 | var2 = aDecoder.decodeBool(forKey: "var2")
166 | }
167 | }
168 |
169 | func encode(with aCoder: NSCoder) {
170 | aCoder.encode(var0, forKey: "var0")
171 | aCoder.encode(var1, forKey: "var1")
172 | aCoder.encode(var2, forKey: "var2")
173 | }
174 | }
175 | ```
176 |
--------------------------------------------------------------------------------
/CodeGenerator.xcodeproj/xcshareddata/xcschemes/Generate....xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
6 |
9 |
10 |
16 |
22 |
23 |
24 |
30 |
36 |
37 |
38 |
39 |
40 |
46 |
47 |
49 |
55 |
56 |
57 |
58 |
59 |
65 |
66 |
67 |
68 |
69 |
70 |
82 |
86 |
87 |
88 |
94 |
95 |
96 |
97 |
98 |
99 |
106 |
108 |
114 |
115 |
116 |
117 |
119 |
120 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/CodeGenerator.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | A01E46781E0FE21500395AED /* InterfaceSignature.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46771E0FE21500395AED /* InterfaceSignature.swift */; };
11 | A01E467E1E0FE57A00395AED /* InterfaceSignatureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E467D1E0FE57A00395AED /* InterfaceSignatureTests.swift */; };
12 | A01E46801E0FE6CB00395AED /* InterfaceSignature.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46771E0FE21500395AED /* InterfaceSignature.swift */; };
13 | A01E46811E0FE6DA00395AED /* String+regexr.swift in Sources */ = {isa = PBXBuildFile; fileRef = A03920901E0F3AEF005A6E89 /* String+regexr.swift */; };
14 | A01E46831E0FF78300395AED /* InterfaceMocker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46821E0FF78300395AED /* InterfaceMocker.swift */; };
15 | A01E46851E0FF94100395AED /* InterfaceDefinition.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46841E0FF94100395AED /* InterfaceDefinition.swift */; };
16 | A01E46871E0FF94C00395AED /* FuncSignature.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46861E0FF94C00395AED /* FuncSignature.swift */; };
17 | A01E468A1E100FB200395AED /* FuncParam.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46891E100FB200395AED /* FuncParam.swift */; };
18 | A01E468B1E1010BB00395AED /* InterfaceDefinition.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46841E0FF94100395AED /* InterfaceDefinition.swift */; };
19 | A01E468C1E1010BE00395AED /* FuncSignature.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46861E0FF94C00395AED /* FuncSignature.swift */; };
20 | A01E468D1E1010C100395AED /* FuncParam.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46891E100FB200395AED /* FuncParam.swift */; };
21 | A01E46911E1017F100395AED /* FuncSignatureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46901E1017F100395AED /* FuncSignatureTests.swift */; };
22 | A01E46931E102CBB00395AED /* VarSignature.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46921E102CBB00395AED /* VarSignature.swift */; };
23 | A01E46951E1030E000395AED /* VarSignatureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46941E1030E000395AED /* VarSignatureTests.swift */; };
24 | A01E46961E10313E00395AED /* VarSignature.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46921E102CBB00395AED /* VarSignature.swift */; };
25 | A01E46A01E105EE900395AED /* FuncMocker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E469F1E105EE900395AED /* FuncMocker.swift */; };
26 | A031BD391E8D1126003235D5 /* GenerateInitCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = A031BD381E8D1126003235D5 /* GenerateInitCommand.swift */; };
27 | A031BD3B1E8D11D6003235D5 /* InitGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A031BD3A1E8D11D6003235D5 /* InitGenerator.swift */; };
28 | A031BD3E1E8D187C003235D5 /* GeneratedInit.txt in Resources */ = {isa = PBXBuildFile; fileRef = A031BD3D1E8D187C003235D5 /* GeneratedInit.txt */; };
29 | A031BD401E8D191E003235D5 /* InitGeneratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A031BD3F1E8D191E003235D5 /* InitGeneratorTests.swift */; };
30 | A031BD411E8D19E9003235D5 /* InitGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A031BD3A1E8D11D6003235D5 /* InitGenerator.swift */; };
31 | A031BD431E8D1DA6003235D5 /* GenerateAsExtensionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = A031BD421E8D1DA6003235D5 /* GenerateAsExtensionCommand.swift */; };
32 | A031BD451E8D2B19003235D5 /* GenerateAfterVarCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = A031BD441E8D2B19003235D5 /* GenerateAfterVarCommand.swift */; };
33 | A039205D1E0F3A7B005A6E89 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A039205C1E0F3A7B005A6E89 /* AppDelegate.swift */; };
34 | A039205F1E0F3A7B005A6E89 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A039205E1E0F3A7B005A6E89 /* ViewController.swift */; };
35 | A03920611E0F3A7B005A6E89 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A03920601E0F3A7B005A6E89 /* Assets.xcassets */; };
36 | A03920641E0F3A7B005A6E89 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A03920621E0F3A7B005A6E89 /* Main.storyboard */; };
37 | A039206F1E0F3A7B005A6E89 /* CodeGeneratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A039206E1E0F3A7B005A6E89 /* CodeGeneratorTests.swift */; };
38 | A03920801E0F3A8B005A6E89 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A039207F1E0F3A8B005A6E89 /* Cocoa.framework */; };
39 | A03920851E0F3A8B005A6E89 /* SourceEditorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A03920841E0F3A8B005A6E89 /* SourceEditorExtension.swift */; };
40 | A03920871E0F3A8B005A6E89 /* GenerateMockCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = A03920861E0F3A8B005A6E89 /* GenerateMockCommand.swift */; };
41 | A039208B1E0F3A8B005A6E89 /* Generate....appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = A039207D1E0F3A8B005A6E89 /* Generate....appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
42 | A03920911E0F3AEF005A6E89 /* String+regexr.swift in Sources */ = {isa = PBXBuildFile; fileRef = A03920901E0F3AEF005A6E89 /* String+regexr.swift */; };
43 | A04453D11E1567EE0063CB99 /* ClosureParamMocker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0E2766A1E156738003CC557 /* ClosureParamMocker.swift */; };
44 | A04453D31E156A080063CB99 /* funcMock.txt in Resources */ = {isa = PBXBuildFile; fileRef = A04453D21E156A080063CB99 /* funcMock.txt */; };
45 | A0636FD41E1294650008CE98 /* EquatableGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0636FD31E1294650008CE98 /* EquatableGenerator.swift */; };
46 | A0636FD61E1299100008CE98 /* EquatableGeneratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0636FD51E1299100008CE98 /* EquatableGeneratorTests.swift */; };
47 | A0636FD81E12997C0008CE98 /* EquatableClazz.txt in Resources */ = {isa = PBXBuildFile; fileRef = A0636FD71E12997C0008CE98 /* EquatableClazz.txt */; };
48 | A0636FDA1E1299A80008CE98 /* GeneratedEquals.txt in Resources */ = {isa = PBXBuildFile; fileRef = A0636FD91E1299A80008CE98 /* GeneratedEquals.txt */; };
49 | A0636FDB1E129B3E0008CE98 /* EquatableGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0636FD31E1294650008CE98 /* EquatableGenerator.swift */; };
50 | A071EB691F04FC86007ACA6E /* SourceError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A071EB681F04FC86007ACA6E /* SourceError.swift */; };
51 | A071EB6A1F04FC86007ACA6E /* SourceError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A071EB681F04FC86007ACA6E /* SourceError.swift */; };
52 | A07FE2771E106CFE00809837 /* FuncMockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A07FE2761E106CFE00809837 /* FuncMockTests.swift */; };
53 | A07FE2781E106D5C00809837 /* FuncMocker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E469F1E105EE900395AED /* FuncMocker.swift */; };
54 | A07FE2791E107AA900809837 /* InterfaceMocker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01E46821E0FF78300395AED /* InterfaceMocker.swift */; };
55 | A07FE2821E108D6900809837 /* InterfaceMockerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A07FE2811E108D6900809837 /* InterfaceMockerTests.swift */; };
56 | A083A3851ED45DD500C9B024 /* CodingGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A083A3841ED45DD500C9B024 /* CodingGenerator.swift */; };
57 | A083A3861ED45DD900C9B024 /* CodingGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A083A3841ED45DD500C9B024 /* CodingGenerator.swift */; };
58 | A083A3B31ED6DC2400C9B024 /* GeneratedNSCoder.txt in Resources */ = {isa = PBXBuildFile; fileRef = A083A3B21ED6DC2400C9B024 /* GeneratedNSCoder.txt */; };
59 | A083A3B51ED6E17D00C9B024 /* NSCodingGeneratorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = A083A3B41ED6E17D00C9B024 /* NSCodingGeneratorTest.swift */; };
60 | A083A3B71ED6EA9000C9B024 /* GenerateCodingCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = A083A3B61ED6EA9000C9B024 /* GenerateCodingCommand.swift */; };
61 | A08C585B1E13C5AA00034B76 /* ClosureType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A08C585A1E13C5AA00034B76 /* ClosureType.swift */; };
62 | A08C585C1E13C5AA00034B76 /* ClosureType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A08C585A1E13C5AA00034B76 /* ClosureType.swift */; };
63 | A08C585E1E13CB8300034B76 /* SwiftType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A08C585D1E13CB8300034B76 /* SwiftType.swift */; };
64 | A08C585F1E13CB8300034B76 /* SwiftType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A08C585D1E13CB8300034B76 /* SwiftType.swift */; };
65 | A0A02CC31E1A60EA001900DC /* Generator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A02CC21E1A60EA001900DC /* Generator.swift */; };
66 | A0A02CC51E1A616C001900DC /* HashableGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A02CC41E1A616C001900DC /* HashableGenerator.swift */; };
67 | A0A02CC71E1A6868001900DC /* HashableGeneratorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A02CC61E1A6868001900DC /* HashableGeneratorTest.swift */; };
68 | A0A02CC91E1A68D8001900DC /* GeneratedHash.txt in Resources */ = {isa = PBXBuildFile; fileRef = A0A02CC81E1A68D8001900DC /* GeneratedHash.txt */; };
69 | A0A02CCA1E1A6A16001900DC /* HashableGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A02CC41E1A616C001900DC /* HashableGenerator.swift */; };
70 | A0A02CCB1E1A6A3F001900DC /* Generator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A02CC21E1A60EA001900DC /* Generator.swift */; };
71 | A0A02CD01E1A6DE3001900DC /* SelectableGeneratorCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A02CCE1E1A6DE3001900DC /* SelectableGeneratorCommand.swift */; };
72 | A0A02CD31E1A7236001900DC /* GenerateEquatableCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A02CD11E1A7236001900DC /* GenerateEquatableCommand.swift */; };
73 | A0A02CD51E1A739A001900DC /* GenerateHashableCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A02CD41E1A739A001900DC /* GenerateHashableCommand.swift */; };
74 | A0A82AE71E11571200F27EA3 /* interface1.txt in Resources */ = {isa = PBXBuildFile; fileRef = A0A82AE61E11571200F27EA3 /* interface1.txt */; };
75 | A0A82AE91E11593800F27EA3 /* interface1Mock.txt in Resources */ = {isa = PBXBuildFile; fileRef = A0A82AE81E11593800F27EA3 /* interface1Mock.txt */; };
76 | A0A82AEB1E1159C200F27EA3 /* NSObject+file.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A82AEA1E1159C200F27EA3 /* NSObject+file.swift */; };
77 | A0A82AEF1E11676B00F27EA3 /* SwiftTypeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A82AEE1E11676B00F27EA3 /* SwiftTypeTests.swift */; };
78 | A0A82B1A1E127BEE00F27EA3 /* AccessLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A82B191E127BEE00F27EA3 /* AccessLevel.swift */; };
79 | A0A82B1C1E127E9F00F27EA3 /* AccessLevelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A82B1B1E127E9F00F27EA3 /* AccessLevelTests.swift */; };
80 | A0A82B1D1E127F1000F27EA3 /* AccessLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0A82B191E127BEE00F27EA3 /* AccessLevel.swift */; };
81 | A0E276531E13F1F6003CC557 /* TypeParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0E276521E13F1F6003CC557 /* TypeParser.swift */; };
82 | A0E276541E13F1FC003CC557 /* TypeParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0E276521E13F1F6003CC557 /* TypeParser.swift */; };
83 | A0E276591E141ED8003CC557 /* SwiftParamMocker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0E276581E141ED8003CC557 /* SwiftParamMocker.swift */; };
84 | A0E2765D1E142670003CC557 /* ParamMocker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0E2765C1E142670003CC557 /* ParamMocker.swift */; };
85 | A0E276651E152F17003CC557 /* ParamMockerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0E276641E152F17003CC557 /* ParamMockerFactory.swift */; };
86 | A0E276661E1542D3003CC557 /* ParamMocker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0E2765C1E142670003CC557 /* ParamMocker.swift */; };
87 | A0E276671E1542DC003CC557 /* ParamMockerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0E276641E152F17003CC557 /* ParamMockerFactory.swift */; };
88 | A0E276681E1542E4003CC557 /* SwiftParamMocker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0E276581E141ED8003CC557 /* SwiftParamMocker.swift */; };
89 | A0E2766B1E156738003CC557 /* ClosureParamMocker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0E2766A1E156738003CC557 /* ClosureParamMocker.swift */; };
90 | /* End PBXBuildFile section */
91 |
92 | /* Begin PBXContainerItemProxy section */
93 | A039206B1E0F3A7B005A6E89 /* PBXContainerItemProxy */ = {
94 | isa = PBXContainerItemProxy;
95 | containerPortal = A03920511E0F3A7B005A6E89 /* Project object */;
96 | proxyType = 1;
97 | remoteGlobalIDString = A03920581E0F3A7B005A6E89;
98 | remoteInfo = CodeGenerator;
99 | };
100 | A03920891E0F3A8B005A6E89 /* PBXContainerItemProxy */ = {
101 | isa = PBXContainerItemProxy;
102 | containerPortal = A03920511E0F3A7B005A6E89 /* Project object */;
103 | proxyType = 1;
104 | remoteGlobalIDString = A039207C1E0F3A8B005A6E89;
105 | remoteInfo = Generate...;
106 | };
107 | /* End PBXContainerItemProxy section */
108 |
109 | /* Begin PBXCopyFilesBuildPhase section */
110 | A039208F1E0F3A8B005A6E89 /* Embed App Extensions */ = {
111 | isa = PBXCopyFilesBuildPhase;
112 | buildActionMask = 2147483647;
113 | dstPath = "";
114 | dstSubfolderSpec = 13;
115 | files = (
116 | A039208B1E0F3A8B005A6E89 /* Generate....appex in Embed App Extensions */,
117 | );
118 | name = "Embed App Extensions";
119 | runOnlyForDeploymentPostprocessing = 0;
120 | };
121 | /* End PBXCopyFilesBuildPhase section */
122 |
123 | /* Begin PBXFileReference section */
124 | A01E46771E0FE21500395AED /* InterfaceSignature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InterfaceSignature.swift; sourceTree = ""; };
125 | A01E467D1E0FE57A00395AED /* InterfaceSignatureTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InterfaceSignatureTests.swift; sourceTree = ""; };
126 | A01E46821E0FF78300395AED /* InterfaceMocker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InterfaceMocker.swift; sourceTree = ""; };
127 | A01E46841E0FF94100395AED /* InterfaceDefinition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InterfaceDefinition.swift; sourceTree = ""; };
128 | A01E46861E0FF94C00395AED /* FuncSignature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FuncSignature.swift; sourceTree = ""; };
129 | A01E46891E100FB200395AED /* FuncParam.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FuncParam.swift; sourceTree = ""; };
130 | A01E46901E1017F100395AED /* FuncSignatureTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FuncSignatureTests.swift; sourceTree = ""; };
131 | A01E46921E102CBB00395AED /* VarSignature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VarSignature.swift; sourceTree = ""; };
132 | A01E46941E1030E000395AED /* VarSignatureTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VarSignatureTests.swift; sourceTree = ""; };
133 | A01E469F1E105EE900395AED /* FuncMocker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FuncMocker.swift; sourceTree = ""; };
134 | A031BD381E8D1126003235D5 /* GenerateInitCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenerateInitCommand.swift; sourceTree = ""; };
135 | A031BD3A1E8D11D6003235D5 /* InitGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InitGenerator.swift; sourceTree = ""; };
136 | A031BD3D1E8D187C003235D5 /* GeneratedInit.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = GeneratedInit.txt; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
137 | A031BD3F1E8D191E003235D5 /* InitGeneratorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InitGeneratorTests.swift; sourceTree = ""; };
138 | A031BD421E8D1DA6003235D5 /* GenerateAsExtensionCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenerateAsExtensionCommand.swift; sourceTree = ""; };
139 | A031BD441E8D2B19003235D5 /* GenerateAfterVarCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenerateAfterVarCommand.swift; sourceTree = ""; };
140 | A03920591E0F3A7B005A6E89 /* CodeGenerator.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CodeGenerator.app; sourceTree = BUILT_PRODUCTS_DIR; };
141 | A039205C1E0F3A7B005A6E89 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
142 | A039205E1E0F3A7B005A6E89 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
143 | A03920601E0F3A7B005A6E89 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
144 | A03920631E0F3A7B005A6E89 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
145 | A03920651E0F3A7B005A6E89 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
146 | A039206A1E0F3A7B005A6E89 /* CodeGeneratorTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CodeGeneratorTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
147 | A039206E1E0F3A7B005A6E89 /* CodeGeneratorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeGeneratorTests.swift; sourceTree = ""; };
148 | A03920701E0F3A7B005A6E89 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
149 | A039207D1E0F3A8B005A6E89 /* Generate....appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Generate....appex; sourceTree = BUILT_PRODUCTS_DIR; };
150 | A039207F1E0F3A8B005A6E89 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
151 | A03920831E0F3A8B005A6E89 /* Generate___.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Generate___.entitlements"; sourceTree = ""; };
152 | A03920841E0F3A8B005A6E89 /* SourceEditorExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceEditorExtension.swift; sourceTree = ""; };
153 | A03920861E0F3A8B005A6E89 /* GenerateMockCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenerateMockCommand.swift; sourceTree = ""; };
154 | A03920881E0F3A8B005A6E89 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
155 | A03920901E0F3AEF005A6E89 /* String+regexr.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+regexr.swift"; sourceTree = ""; };
156 | A04453D21E156A080063CB99 /* funcMock.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = funcMock.txt; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
157 | A0636FD31E1294650008CE98 /* EquatableGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EquatableGenerator.swift; sourceTree = ""; };
158 | A0636FD51E1299100008CE98 /* EquatableGeneratorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EquatableGeneratorTests.swift; sourceTree = ""; };
159 | A0636FD71E12997C0008CE98 /* EquatableClazz.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EquatableClazz.txt; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
160 | A0636FD91E1299A80008CE98 /* GeneratedEquals.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = GeneratedEquals.txt; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
161 | A071EB681F04FC86007ACA6E /* SourceError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SourceError.swift; sourceTree = ""; };
162 | A07FE2761E106CFE00809837 /* FuncMockTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FuncMockTests.swift; sourceTree = ""; };
163 | A07FE2811E108D6900809837 /* InterfaceMockerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InterfaceMockerTests.swift; sourceTree = ""; };
164 | A083A3841ED45DD500C9B024 /* CodingGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodingGenerator.swift; sourceTree = ""; };
165 | A083A3B21ED6DC2400C9B024 /* GeneratedNSCoder.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = GeneratedNSCoder.txt; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
166 | A083A3B41ED6E17D00C9B024 /* NSCodingGeneratorTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSCodingGeneratorTest.swift; sourceTree = ""; };
167 | A083A3B61ED6EA9000C9B024 /* GenerateCodingCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenerateCodingCommand.swift; sourceTree = ""; };
168 | A08C585A1E13C5AA00034B76 /* ClosureType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClosureType.swift; sourceTree = ""; };
169 | A08C585D1E13CB8300034B76 /* SwiftType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftType.swift; sourceTree = ""; };
170 | A0A02CC21E1A60EA001900DC /* Generator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Generator.swift; sourceTree = ""; };
171 | A0A02CC41E1A616C001900DC /* HashableGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HashableGenerator.swift; sourceTree = ""; };
172 | A0A02CC61E1A6868001900DC /* HashableGeneratorTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HashableGeneratorTest.swift; sourceTree = ""; };
173 | A0A02CC81E1A68D8001900DC /* GeneratedHash.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = GeneratedHash.txt; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
174 | A0A02CCE1E1A6DE3001900DC /* SelectableGeneratorCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectableGeneratorCommand.swift; sourceTree = ""; };
175 | A0A02CD11E1A7236001900DC /* GenerateEquatableCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenerateEquatableCommand.swift; sourceTree = ""; };
176 | A0A02CD41E1A739A001900DC /* GenerateHashableCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenerateHashableCommand.swift; sourceTree = ""; };
177 | A0A82AE61E11571200F27EA3 /* interface1.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = interface1.txt; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
178 | A0A82AE81E11593800F27EA3 /* interface1Mock.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = interface1Mock.txt; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
179 | A0A82AEA1E1159C200F27EA3 /* NSObject+file.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSObject+file.swift"; sourceTree = ""; };
180 | A0A82AEE1E11676B00F27EA3 /* SwiftTypeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftTypeTests.swift; sourceTree = ""; };
181 | A0A82B191E127BEE00F27EA3 /* AccessLevel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccessLevel.swift; sourceTree = ""; };
182 | A0A82B1B1E127E9F00F27EA3 /* AccessLevelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccessLevelTests.swift; sourceTree = ""; };
183 | A0E276521E13F1F6003CC557 /* TypeParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeParser.swift; sourceTree = ""; };
184 | A0E276581E141ED8003CC557 /* SwiftParamMocker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftParamMocker.swift; sourceTree = ""; };
185 | A0E2765C1E142670003CC557 /* ParamMocker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParamMocker.swift; sourceTree = ""; };
186 | A0E276641E152F17003CC557 /* ParamMockerFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParamMockerFactory.swift; sourceTree = ""; };
187 | A0E2766A1E156738003CC557 /* ClosureParamMocker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClosureParamMocker.swift; sourceTree = ""; };
188 | /* End PBXFileReference section */
189 |
190 | /* Begin PBXFrameworksBuildPhase section */
191 | A03920561E0F3A7B005A6E89 /* Frameworks */ = {
192 | isa = PBXFrameworksBuildPhase;
193 | buildActionMask = 2147483647;
194 | files = (
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | };
198 | A03920671E0F3A7B005A6E89 /* Frameworks */ = {
199 | isa = PBXFrameworksBuildPhase;
200 | buildActionMask = 2147483647;
201 | files = (
202 | );
203 | runOnlyForDeploymentPostprocessing = 0;
204 | };
205 | A039207A1E0F3A8B005A6E89 /* Frameworks */ = {
206 | isa = PBXFrameworksBuildPhase;
207 | buildActionMask = 2147483647;
208 | files = (
209 | A03920801E0F3A8B005A6E89 /* Cocoa.framework in Frameworks */,
210 | );
211 | runOnlyForDeploymentPostprocessing = 0;
212 | };
213 | /* End PBXFrameworksBuildPhase section */
214 |
215 | /* Begin PBXGroup section */
216 | A01E46881E0FF95900395AED /* Source */ = {
217 | isa = PBXGroup;
218 | children = (
219 | A0E276521E13F1F6003CC557 /* TypeParser.swift */,
220 | A08C585D1E13CB8300034B76 /* SwiftType.swift */,
221 | A08C585A1E13C5AA00034B76 /* ClosureType.swift */,
222 | A01E46771E0FE21500395AED /* InterfaceSignature.swift */,
223 | A01E46841E0FF94100395AED /* InterfaceDefinition.swift */,
224 | A01E46861E0FF94C00395AED /* FuncSignature.swift */,
225 | A01E46891E100FB200395AED /* FuncParam.swift */,
226 | A01E46921E102CBB00395AED /* VarSignature.swift */,
227 | A0A82B191E127BEE00F27EA3 /* AccessLevel.swift */,
228 | );
229 | name = Source;
230 | sourceTree = "";
231 | };
232 | A01E469E1E105EB400395AED /* Mocker */ = {
233 | isa = PBXGroup;
234 | children = (
235 | A01E469F1E105EE900395AED /* FuncMocker.swift */,
236 | A01E46821E0FF78300395AED /* InterfaceMocker.swift */,
237 | A0E2765C1E142670003CC557 /* ParamMocker.swift */,
238 | A0E276581E141ED8003CC557 /* SwiftParamMocker.swift */,
239 | A0E2766A1E156738003CC557 /* ClosureParamMocker.swift */,
240 | A0E276641E152F17003CC557 /* ParamMockerFactory.swift */,
241 | );
242 | name = Mocker;
243 | sourceTree = "";
244 | };
245 | A03920501E0F3A7B005A6E89 = {
246 | isa = PBXGroup;
247 | children = (
248 | A039205B1E0F3A7B005A6E89 /* CodeGenerator */,
249 | A039206D1E0F3A7B005A6E89 /* CodeGeneratorTests */,
250 | A03920811E0F3A8B005A6E89 /* Generate... */,
251 | A039207E1E0F3A8B005A6E89 /* Frameworks */,
252 | A039205A1E0F3A7B005A6E89 /* Products */,
253 | );
254 | sourceTree = "";
255 | };
256 | A039205A1E0F3A7B005A6E89 /* Products */ = {
257 | isa = PBXGroup;
258 | children = (
259 | A03920591E0F3A7B005A6E89 /* CodeGenerator.app */,
260 | A039206A1E0F3A7B005A6E89 /* CodeGeneratorTests.xctest */,
261 | A039207D1E0F3A8B005A6E89 /* Generate....appex */,
262 | );
263 | name = Products;
264 | sourceTree = "";
265 | };
266 | A039205B1E0F3A7B005A6E89 /* CodeGenerator */ = {
267 | isa = PBXGroup;
268 | children = (
269 | A039205C1E0F3A7B005A6E89 /* AppDelegate.swift */,
270 | A039205E1E0F3A7B005A6E89 /* ViewController.swift */,
271 | A03920601E0F3A7B005A6E89 /* Assets.xcassets */,
272 | A03920621E0F3A7B005A6E89 /* Main.storyboard */,
273 | A03920651E0F3A7B005A6E89 /* Info.plist */,
274 | );
275 | path = CodeGenerator;
276 | sourceTree = "";
277 | };
278 | A039206D1E0F3A7B005A6E89 /* CodeGeneratorTests */ = {
279 | isa = PBXGroup;
280 | children = (
281 | A01E467D1E0FE57A00395AED /* InterfaceSignatureTests.swift */,
282 | A039206E1E0F3A7B005A6E89 /* CodeGeneratorTests.swift */,
283 | A01E46901E1017F100395AED /* FuncSignatureTests.swift */,
284 | A01E46941E1030E000395AED /* VarSignatureTests.swift */,
285 | A07FE2761E106CFE00809837 /* FuncMockTests.swift */,
286 | A07FE2811E108D6900809837 /* InterfaceMockerTests.swift */,
287 | A0A82B1B1E127E9F00F27EA3 /* AccessLevelTests.swift */,
288 | A0A82AEE1E11676B00F27EA3 /* SwiftTypeTests.swift */,
289 | A0636FD51E1299100008CE98 /* EquatableGeneratorTests.swift */,
290 | A0A02CC61E1A6868001900DC /* HashableGeneratorTest.swift */,
291 | A083A3B41ED6E17D00C9B024 /* NSCodingGeneratorTest.swift */,
292 | A031BD3F1E8D191E003235D5 /* InitGeneratorTests.swift */,
293 | A0A82AEA1E1159C200F27EA3 /* NSObject+file.swift */,
294 | A0A82AE61E11571200F27EA3 /* interface1.txt */,
295 | A0A82AE81E11593800F27EA3 /* interface1Mock.txt */,
296 | A03920701E0F3A7B005A6E89 /* Info.plist */,
297 | A0636FD71E12997C0008CE98 /* EquatableClazz.txt */,
298 | A083A3B21ED6DC2400C9B024 /* GeneratedNSCoder.txt */,
299 | A0636FD91E1299A80008CE98 /* GeneratedEquals.txt */,
300 | A031BD3D1E8D187C003235D5 /* GeneratedInit.txt */,
301 | A0A02CC81E1A68D8001900DC /* GeneratedHash.txt */,
302 | A04453D21E156A080063CB99 /* funcMock.txt */,
303 | );
304 | path = CodeGeneratorTests;
305 | sourceTree = "";
306 | };
307 | A039207E1E0F3A8B005A6E89 /* Frameworks */ = {
308 | isa = PBXGroup;
309 | children = (
310 | A039207F1E0F3A8B005A6E89 /* Cocoa.framework */,
311 | );
312 | name = Frameworks;
313 | sourceTree = "";
314 | };
315 | A03920811E0F3A8B005A6E89 /* Generate... */ = {
316 | isa = PBXGroup;
317 | children = (
318 | A071EB681F04FC86007ACA6E /* SourceError.swift */,
319 | A0636FD21E12944B0008CE98 /* Generator */,
320 | A01E469E1E105EB400395AED /* Mocker */,
321 | A01E46881E0FF95900395AED /* Source */,
322 | A03920841E0F3A8B005A6E89 /* SourceEditorExtension.swift */,
323 | A031BD441E8D2B19003235D5 /* GenerateAfterVarCommand.swift */,
324 | A031BD381E8D1126003235D5 /* GenerateInitCommand.swift */,
325 | A0A02CCE1E1A6DE3001900DC /* SelectableGeneratorCommand.swift */,
326 | A031BD421E8D1DA6003235D5 /* GenerateAsExtensionCommand.swift */,
327 | A0A02CD11E1A7236001900DC /* GenerateEquatableCommand.swift */,
328 | A0A02CD41E1A739A001900DC /* GenerateHashableCommand.swift */,
329 | A083A3B61ED6EA9000C9B024 /* GenerateCodingCommand.swift */,
330 | A03920861E0F3A8B005A6E89 /* GenerateMockCommand.swift */,
331 | A03920901E0F3AEF005A6E89 /* String+regexr.swift */,
332 | A03920881E0F3A8B005A6E89 /* Info.plist */,
333 | A03920821E0F3A8B005A6E89 /* Supporting Files */,
334 | );
335 | path = Generate...;
336 | sourceTree = "";
337 | };
338 | A03920821E0F3A8B005A6E89 /* Supporting Files */ = {
339 | isa = PBXGroup;
340 | children = (
341 | A03920831E0F3A8B005A6E89 /* Generate___.entitlements */,
342 | );
343 | name = "Supporting Files";
344 | sourceTree = "";
345 | };
346 | A0636FD21E12944B0008CE98 /* Generator */ = {
347 | isa = PBXGroup;
348 | children = (
349 | A0A02CC21E1A60EA001900DC /* Generator.swift */,
350 | A0636FD31E1294650008CE98 /* EquatableGenerator.swift */,
351 | A0A02CC41E1A616C001900DC /* HashableGenerator.swift */,
352 | A031BD3A1E8D11D6003235D5 /* InitGenerator.swift */,
353 | A083A3841ED45DD500C9B024 /* CodingGenerator.swift */,
354 | );
355 | name = Generator;
356 | sourceTree = "";
357 | };
358 | /* End PBXGroup section */
359 |
360 | /* Begin PBXNativeTarget section */
361 | A03920581E0F3A7B005A6E89 /* CodeGenerator */ = {
362 | isa = PBXNativeTarget;
363 | buildConfigurationList = A03920731E0F3A7B005A6E89 /* Build configuration list for PBXNativeTarget "CodeGenerator" */;
364 | buildPhases = (
365 | A03920551E0F3A7B005A6E89 /* Sources */,
366 | A03920561E0F3A7B005A6E89 /* Frameworks */,
367 | A03920571E0F3A7B005A6E89 /* Resources */,
368 | A039208F1E0F3A8B005A6E89 /* Embed App Extensions */,
369 | );
370 | buildRules = (
371 | );
372 | dependencies = (
373 | A039208A1E0F3A8B005A6E89 /* PBXTargetDependency */,
374 | );
375 | name = CodeGenerator;
376 | productName = CodeGenerator;
377 | productReference = A03920591E0F3A7B005A6E89 /* CodeGenerator.app */;
378 | productType = "com.apple.product-type.application";
379 | };
380 | A03920691E0F3A7B005A6E89 /* CodeGeneratorTests */ = {
381 | isa = PBXNativeTarget;
382 | buildConfigurationList = A03920761E0F3A7B005A6E89 /* Build configuration list for PBXNativeTarget "CodeGeneratorTests" */;
383 | buildPhases = (
384 | A03920661E0F3A7B005A6E89 /* Sources */,
385 | A03920671E0F3A7B005A6E89 /* Frameworks */,
386 | A03920681E0F3A7B005A6E89 /* Resources */,
387 | );
388 | buildRules = (
389 | );
390 | dependencies = (
391 | A039206C1E0F3A7B005A6E89 /* PBXTargetDependency */,
392 | );
393 | name = CodeGeneratorTests;
394 | productName = CodeGeneratorTests;
395 | productReference = A039206A1E0F3A7B005A6E89 /* CodeGeneratorTests.xctest */;
396 | productType = "com.apple.product-type.bundle.unit-test";
397 | };
398 | A039207C1E0F3A8B005A6E89 /* Generate... */ = {
399 | isa = PBXNativeTarget;
400 | buildConfigurationList = A039208C1E0F3A8B005A6E89 /* Build configuration list for PBXNativeTarget "Generate..." */;
401 | buildPhases = (
402 | A03920791E0F3A8B005A6E89 /* Sources */,
403 | A039207A1E0F3A8B005A6E89 /* Frameworks */,
404 | A039207B1E0F3A8B005A6E89 /* Resources */,
405 | );
406 | buildRules = (
407 | );
408 | dependencies = (
409 | );
410 | name = Generate...;
411 | productName = Generate...;
412 | productReference = A039207D1E0F3A8B005A6E89 /* Generate....appex */;
413 | productType = "com.apple.product-type.xcode-extension";
414 | };
415 | /* End PBXNativeTarget section */
416 |
417 | /* Begin PBXProject section */
418 | A03920511E0F3A7B005A6E89 /* Project object */ = {
419 | isa = PBXProject;
420 | attributes = {
421 | LastSwiftUpdateCheck = 0820;
422 | LastUpgradeCheck = 0920;
423 | ORGANIZATIONNAME = wangjie;
424 | TargetAttributes = {
425 | A03920581E0F3A7B005A6E89 = {
426 | CreatedOnToolsVersion = 8.2;
427 | DevelopmentTeam = 5C59L2E3AR;
428 | LastSwiftMigration = 0920;
429 | ProvisioningStyle = Automatic;
430 | };
431 | A03920691E0F3A7B005A6E89 = {
432 | CreatedOnToolsVersion = 8.2;
433 | DevelopmentTeam = 5C59L2E3AR;
434 | LastSwiftMigration = 0920;
435 | ProvisioningStyle = Automatic;
436 | TestTargetID = A03920581E0F3A7B005A6E89;
437 | };
438 | A039207C1E0F3A8B005A6E89 = {
439 | CreatedOnToolsVersion = 8.2;
440 | DevelopmentTeam = 5C59L2E3AR;
441 | LastSwiftMigration = 0920;
442 | ProvisioningStyle = Automatic;
443 | };
444 | };
445 | };
446 | buildConfigurationList = A03920541E0F3A7B005A6E89 /* Build configuration list for PBXProject "CodeGenerator" */;
447 | compatibilityVersion = "Xcode 3.2";
448 | developmentRegion = English;
449 | hasScannedForEncodings = 0;
450 | knownRegions = (
451 | en,
452 | Base,
453 | );
454 | mainGroup = A03920501E0F3A7B005A6E89;
455 | productRefGroup = A039205A1E0F3A7B005A6E89 /* Products */;
456 | projectDirPath = "";
457 | projectRoot = "";
458 | targets = (
459 | A03920581E0F3A7B005A6E89 /* CodeGenerator */,
460 | A03920691E0F3A7B005A6E89 /* CodeGeneratorTests */,
461 | A039207C1E0F3A8B005A6E89 /* Generate... */,
462 | );
463 | };
464 | /* End PBXProject section */
465 |
466 | /* Begin PBXResourcesBuildPhase section */
467 | A03920571E0F3A7B005A6E89 /* Resources */ = {
468 | isa = PBXResourcesBuildPhase;
469 | buildActionMask = 2147483647;
470 | files = (
471 | A03920611E0F3A7B005A6E89 /* Assets.xcassets in Resources */,
472 | A03920641E0F3A7B005A6E89 /* Main.storyboard in Resources */,
473 | );
474 | runOnlyForDeploymentPostprocessing = 0;
475 | };
476 | A03920681E0F3A7B005A6E89 /* Resources */ = {
477 | isa = PBXResourcesBuildPhase;
478 | buildActionMask = 2147483647;
479 | files = (
480 | A0A02CC91E1A68D8001900DC /* GeneratedHash.txt in Resources */,
481 | A0A82AE91E11593800F27EA3 /* interface1Mock.txt in Resources */,
482 | A0636FDA1E1299A80008CE98 /* GeneratedEquals.txt in Resources */,
483 | A0A82AE71E11571200F27EA3 /* interface1.txt in Resources */,
484 | A0636FD81E12997C0008CE98 /* EquatableClazz.txt in Resources */,
485 | A083A3B31ED6DC2400C9B024 /* GeneratedNSCoder.txt in Resources */,
486 | A031BD3E1E8D187C003235D5 /* GeneratedInit.txt in Resources */,
487 | A04453D31E156A080063CB99 /* funcMock.txt in Resources */,
488 | );
489 | runOnlyForDeploymentPostprocessing = 0;
490 | };
491 | A039207B1E0F3A8B005A6E89 /* Resources */ = {
492 | isa = PBXResourcesBuildPhase;
493 | buildActionMask = 2147483647;
494 | files = (
495 | );
496 | runOnlyForDeploymentPostprocessing = 0;
497 | };
498 | /* End PBXResourcesBuildPhase section */
499 |
500 | /* Begin PBXSourcesBuildPhase section */
501 | A03920551E0F3A7B005A6E89 /* Sources */ = {
502 | isa = PBXSourcesBuildPhase;
503 | buildActionMask = 2147483647;
504 | files = (
505 | A01E46961E10313E00395AED /* VarSignature.swift in Sources */,
506 | A07FE2781E106D5C00809837 /* FuncMocker.swift in Sources */,
507 | A0E276681E1542E4003CC557 /* SwiftParamMocker.swift in Sources */,
508 | A039205F1E0F3A7B005A6E89 /* ViewController.swift in Sources */,
509 | A01E46811E0FE6DA00395AED /* String+regexr.swift in Sources */,
510 | A01E468C1E1010BE00395AED /* FuncSignature.swift in Sources */,
511 | A01E468B1E1010BB00395AED /* InterfaceDefinition.swift in Sources */,
512 | A071EB691F04FC86007ACA6E /* SourceError.swift in Sources */,
513 | A039205D1E0F3A7B005A6E89 /* AppDelegate.swift in Sources */,
514 | A01E46801E0FE6CB00395AED /* InterfaceSignature.swift in Sources */,
515 | A0E276671E1542DC003CC557 /* ParamMockerFactory.swift in Sources */,
516 | A04453D11E1567EE0063CB99 /* ClosureParamMocker.swift in Sources */,
517 | A08C585B1E13C5AA00034B76 /* ClosureType.swift in Sources */,
518 | A0E276541E13F1FC003CC557 /* TypeParser.swift in Sources */,
519 | A031BD411E8D19E9003235D5 /* InitGenerator.swift in Sources */,
520 | A07FE2791E107AA900809837 /* InterfaceMocker.swift in Sources */,
521 | A0A82B1D1E127F1000F27EA3 /* AccessLevel.swift in Sources */,
522 | A083A3861ED45DD900C9B024 /* CodingGenerator.swift in Sources */,
523 | A08C585E1E13CB8300034B76 /* SwiftType.swift in Sources */,
524 | A0636FDB1E129B3E0008CE98 /* EquatableGenerator.swift in Sources */,
525 | A0A02CCA1E1A6A16001900DC /* HashableGenerator.swift in Sources */,
526 | A0A02CCB1E1A6A3F001900DC /* Generator.swift in Sources */,
527 | A0E276661E1542D3003CC557 /* ParamMocker.swift in Sources */,
528 | A01E468D1E1010C100395AED /* FuncParam.swift in Sources */,
529 | );
530 | runOnlyForDeploymentPostprocessing = 0;
531 | };
532 | A03920661E0F3A7B005A6E89 /* Sources */ = {
533 | isa = PBXSourcesBuildPhase;
534 | buildActionMask = 2147483647;
535 | files = (
536 | A01E46951E1030E000395AED /* VarSignatureTests.swift in Sources */,
537 | A0A82AEF1E11676B00F27EA3 /* SwiftTypeTests.swift in Sources */,
538 | A0A02CC71E1A6868001900DC /* HashableGeneratorTest.swift in Sources */,
539 | A0636FD61E1299100008CE98 /* EquatableGeneratorTests.swift in Sources */,
540 | A083A3B51ED6E17D00C9B024 /* NSCodingGeneratorTest.swift in Sources */,
541 | A01E467E1E0FE57A00395AED /* InterfaceSignatureTests.swift in Sources */,
542 | A01E46911E1017F100395AED /* FuncSignatureTests.swift in Sources */,
543 | A07FE2771E106CFE00809837 /* FuncMockTests.swift in Sources */,
544 | A0A82AEB1E1159C200F27EA3 /* NSObject+file.swift in Sources */,
545 | A07FE2821E108D6900809837 /* InterfaceMockerTests.swift in Sources */,
546 | A031BD401E8D191E003235D5 /* InitGeneratorTests.swift in Sources */,
547 | A039206F1E0F3A7B005A6E89 /* CodeGeneratorTests.swift in Sources */,
548 | A0A82B1C1E127E9F00F27EA3 /* AccessLevelTests.swift in Sources */,
549 | );
550 | runOnlyForDeploymentPostprocessing = 0;
551 | };
552 | A03920791E0F3A8B005A6E89 /* Sources */ = {
553 | isa = PBXSourcesBuildPhase;
554 | buildActionMask = 2147483647;
555 | files = (
556 | A01E46931E102CBB00395AED /* VarSignature.swift in Sources */,
557 | A03920851E0F3A8B005A6E89 /* SourceEditorExtension.swift in Sources */,
558 | A083A3B71ED6EA9000C9B024 /* GenerateCodingCommand.swift in Sources */,
559 | A0E2766B1E156738003CC557 /* ClosureParamMocker.swift in Sources */,
560 | A0A02CD31E1A7236001900DC /* GenerateEquatableCommand.swift in Sources */,
561 | A031BD391E8D1126003235D5 /* GenerateInitCommand.swift in Sources */,
562 | A0A02CD01E1A6DE3001900DC /* SelectableGeneratorCommand.swift in Sources */,
563 | A08C585F1E13CB8300034B76 /* SwiftType.swift in Sources */,
564 | A01E46851E0FF94100395AED /* InterfaceDefinition.swift in Sources */,
565 | A01E46A01E105EE900395AED /* FuncMocker.swift in Sources */,
566 | A03920911E0F3AEF005A6E89 /* String+regexr.swift in Sources */,
567 | A08C585C1E13C5AA00034B76 /* ClosureType.swift in Sources */,
568 | A031BD3B1E8D11D6003235D5 /* InitGenerator.swift in Sources */,
569 | A0A82B1A1E127BEE00F27EA3 /* AccessLevel.swift in Sources */,
570 | A031BD451E8D2B19003235D5 /* GenerateAfterVarCommand.swift in Sources */,
571 | A083A3851ED45DD500C9B024 /* CodingGenerator.swift in Sources */,
572 | A01E46871E0FF94C00395AED /* FuncSignature.swift in Sources */,
573 | A0E276591E141ED8003CC557 /* SwiftParamMocker.swift in Sources */,
574 | A0E276531E13F1F6003CC557 /* TypeParser.swift in Sources */,
575 | A0E276651E152F17003CC557 /* ParamMockerFactory.swift in Sources */,
576 | A031BD431E8D1DA6003235D5 /* GenerateAsExtensionCommand.swift in Sources */,
577 | A0636FD41E1294650008CE98 /* EquatableGenerator.swift in Sources */,
578 | A071EB6A1F04FC86007ACA6E /* SourceError.swift in Sources */,
579 | A01E46781E0FE21500395AED /* InterfaceSignature.swift in Sources */,
580 | A01E46831E0FF78300395AED /* InterfaceMocker.swift in Sources */,
581 | A0A02CC51E1A616C001900DC /* HashableGenerator.swift in Sources */,
582 | A03920871E0F3A8B005A6E89 /* GenerateMockCommand.swift in Sources */,
583 | A0A02CC31E1A60EA001900DC /* Generator.swift in Sources */,
584 | A0E2765D1E142670003CC557 /* ParamMocker.swift in Sources */,
585 | A01E468A1E100FB200395AED /* FuncParam.swift in Sources */,
586 | A0A02CD51E1A739A001900DC /* GenerateHashableCommand.swift in Sources */,
587 | );
588 | runOnlyForDeploymentPostprocessing = 0;
589 | };
590 | /* End PBXSourcesBuildPhase section */
591 |
592 | /* Begin PBXTargetDependency section */
593 | A039206C1E0F3A7B005A6E89 /* PBXTargetDependency */ = {
594 | isa = PBXTargetDependency;
595 | target = A03920581E0F3A7B005A6E89 /* CodeGenerator */;
596 | targetProxy = A039206B1E0F3A7B005A6E89 /* PBXContainerItemProxy */;
597 | };
598 | A039208A1E0F3A8B005A6E89 /* PBXTargetDependency */ = {
599 | isa = PBXTargetDependency;
600 | target = A039207C1E0F3A8B005A6E89 /* Generate... */;
601 | targetProxy = A03920891E0F3A8B005A6E89 /* PBXContainerItemProxy */;
602 | };
603 | /* End PBXTargetDependency section */
604 |
605 | /* Begin PBXVariantGroup section */
606 | A03920621E0F3A7B005A6E89 /* Main.storyboard */ = {
607 | isa = PBXVariantGroup;
608 | children = (
609 | A03920631E0F3A7B005A6E89 /* Base */,
610 | );
611 | name = Main.storyboard;
612 | sourceTree = "";
613 | };
614 | /* End PBXVariantGroup section */
615 |
616 | /* Begin XCBuildConfiguration section */
617 | A03920711E0F3A7B005A6E89 /* Debug */ = {
618 | isa = XCBuildConfiguration;
619 | buildSettings = {
620 | ALWAYS_SEARCH_USER_PATHS = NO;
621 | CLANG_ANALYZER_NONNULL = YES;
622 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
623 | CLANG_CXX_LIBRARY = "libc++";
624 | CLANG_ENABLE_MODULES = YES;
625 | CLANG_ENABLE_OBJC_ARC = YES;
626 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
627 | CLANG_WARN_BOOL_CONVERSION = YES;
628 | CLANG_WARN_COMMA = YES;
629 | CLANG_WARN_CONSTANT_CONVERSION = YES;
630 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
631 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
632 | CLANG_WARN_EMPTY_BODY = YES;
633 | CLANG_WARN_ENUM_CONVERSION = YES;
634 | CLANG_WARN_INFINITE_RECURSION = YES;
635 | CLANG_WARN_INT_CONVERSION = YES;
636 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
637 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
638 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
639 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
640 | CLANG_WARN_STRICT_PROTOTYPES = YES;
641 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
642 | CLANG_WARN_UNREACHABLE_CODE = YES;
643 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
644 | CODE_SIGN_IDENTITY = "-";
645 | COPY_PHASE_STRIP = NO;
646 | DEBUG_INFORMATION_FORMAT = dwarf;
647 | ENABLE_STRICT_OBJC_MSGSEND = YES;
648 | ENABLE_TESTABILITY = YES;
649 | GCC_C_LANGUAGE_STANDARD = gnu99;
650 | GCC_DYNAMIC_NO_PIC = NO;
651 | GCC_NO_COMMON_BLOCKS = YES;
652 | GCC_OPTIMIZATION_LEVEL = 0;
653 | GCC_PREPROCESSOR_DEFINITIONS = (
654 | "DEBUG=1",
655 | "$(inherited)",
656 | );
657 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
658 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
659 | GCC_WARN_UNDECLARED_SELECTOR = YES;
660 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
661 | GCC_WARN_UNUSED_FUNCTION = YES;
662 | GCC_WARN_UNUSED_VARIABLE = YES;
663 | MACOSX_DEPLOYMENT_TARGET = 10.12;
664 | MTL_ENABLE_DEBUG_INFO = YES;
665 | ONLY_ACTIVE_ARCH = YES;
666 | SDKROOT = macosx;
667 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
668 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
669 | };
670 | name = Debug;
671 | };
672 | A03920721E0F3A7B005A6E89 /* Release */ = {
673 | isa = XCBuildConfiguration;
674 | buildSettings = {
675 | ALWAYS_SEARCH_USER_PATHS = NO;
676 | CLANG_ANALYZER_NONNULL = YES;
677 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
678 | CLANG_CXX_LIBRARY = "libc++";
679 | CLANG_ENABLE_MODULES = YES;
680 | CLANG_ENABLE_OBJC_ARC = YES;
681 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
682 | CLANG_WARN_BOOL_CONVERSION = YES;
683 | CLANG_WARN_COMMA = YES;
684 | CLANG_WARN_CONSTANT_CONVERSION = YES;
685 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
686 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
687 | CLANG_WARN_EMPTY_BODY = YES;
688 | CLANG_WARN_ENUM_CONVERSION = YES;
689 | CLANG_WARN_INFINITE_RECURSION = YES;
690 | CLANG_WARN_INT_CONVERSION = YES;
691 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
692 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
693 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
694 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
695 | CLANG_WARN_STRICT_PROTOTYPES = YES;
696 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
697 | CLANG_WARN_UNREACHABLE_CODE = YES;
698 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
699 | CODE_SIGN_IDENTITY = "-";
700 | COPY_PHASE_STRIP = NO;
701 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
702 | ENABLE_NS_ASSERTIONS = NO;
703 | ENABLE_STRICT_OBJC_MSGSEND = YES;
704 | GCC_C_LANGUAGE_STANDARD = gnu99;
705 | GCC_NO_COMMON_BLOCKS = YES;
706 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
707 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
708 | GCC_WARN_UNDECLARED_SELECTOR = YES;
709 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
710 | GCC_WARN_UNUSED_FUNCTION = YES;
711 | GCC_WARN_UNUSED_VARIABLE = YES;
712 | MACOSX_DEPLOYMENT_TARGET = 10.12;
713 | MTL_ENABLE_DEBUG_INFO = NO;
714 | SDKROOT = macosx;
715 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
716 | };
717 | name = Release;
718 | };
719 | A03920741E0F3A7B005A6E89 /* Debug */ = {
720 | isa = XCBuildConfiguration;
721 | buildSettings = {
722 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
723 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
724 | CODE_SIGN_IDENTITY = "";
725 | COMBINE_HIDPI_IMAGES = YES;
726 | DEVELOPMENT_TEAM = 5C59L2E3AR;
727 | INFOPLIST_FILE = CodeGenerator/Info.plist;
728 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
729 | PRODUCT_BUNDLE_IDENTIFIER = com.wangjie.CodeGenerator;
730 | PRODUCT_NAME = "$(TARGET_NAME)";
731 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
732 | SWIFT_VERSION = 4.0;
733 | };
734 | name = Debug;
735 | };
736 | A03920751E0F3A7B005A6E89 /* Release */ = {
737 | isa = XCBuildConfiguration;
738 | buildSettings = {
739 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
740 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
741 | CODE_SIGN_IDENTITY = "";
742 | COMBINE_HIDPI_IMAGES = YES;
743 | DEVELOPMENT_TEAM = 5C59L2E3AR;
744 | INFOPLIST_FILE = CodeGenerator/Info.plist;
745 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
746 | PRODUCT_BUNDLE_IDENTIFIER = com.wangjie.CodeGenerator;
747 | PRODUCT_NAME = "$(TARGET_NAME)";
748 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
749 | SWIFT_VERSION = 4.0;
750 | };
751 | name = Release;
752 | };
753 | A03920771E0F3A7B005A6E89 /* Debug */ = {
754 | isa = XCBuildConfiguration;
755 | buildSettings = {
756 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
757 | BUNDLE_LOADER = "$(TEST_HOST)";
758 | CODE_SIGN_IDENTITY = "Mac Developer";
759 | COMBINE_HIDPI_IMAGES = YES;
760 | DEVELOPMENT_TEAM = 5C59L2E3AR;
761 | INFOPLIST_FILE = CodeGeneratorTests/Info.plist;
762 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
763 | PRODUCT_BUNDLE_IDENTIFIER = com.wangjie.CodeGeneratorTests;
764 | PRODUCT_NAME = "$(TARGET_NAME)";
765 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
766 | SWIFT_VERSION = 4.0;
767 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CodeGenerator.app/Contents/MacOS/CodeGenerator";
768 | };
769 | name = Debug;
770 | };
771 | A03920781E0F3A7B005A6E89 /* Release */ = {
772 | isa = XCBuildConfiguration;
773 | buildSettings = {
774 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
775 | BUNDLE_LOADER = "$(TEST_HOST)";
776 | CODE_SIGN_IDENTITY = "Mac Developer";
777 | COMBINE_HIDPI_IMAGES = YES;
778 | DEVELOPMENT_TEAM = 5C59L2E3AR;
779 | INFOPLIST_FILE = CodeGeneratorTests/Info.plist;
780 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
781 | PRODUCT_BUNDLE_IDENTIFIER = com.wangjie.CodeGeneratorTests;
782 | PRODUCT_NAME = "$(TARGET_NAME)";
783 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
784 | SWIFT_VERSION = 4.0;
785 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CodeGenerator.app/Contents/MacOS/CodeGenerator";
786 | };
787 | name = Release;
788 | };
789 | A039208D1E0F3A8B005A6E89 /* Debug */ = {
790 | isa = XCBuildConfiguration;
791 | buildSettings = {
792 | CODE_SIGN_ENTITLEMENTS = "Generate.../Generate___.entitlements";
793 | CODE_SIGN_IDENTITY = "Mac Developer";
794 | COMBINE_HIDPI_IMAGES = YES;
795 | DEVELOPMENT_TEAM = 5C59L2E3AR;
796 | INFOPLIST_FILE = Generate.../Info.plist;
797 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks";
798 | MACOSX_DEPLOYMENT_TARGET = 10.11;
799 | PRODUCT_BUNDLE_IDENTIFIER = com.wangjie.CodeGenerator.Generate;
800 | PRODUCT_NAME = "$(TARGET_NAME)";
801 | PROVISIONING_PROFILE = "";
802 | PROVISIONING_PROFILE_SPECIFIER = "";
803 | SKIP_INSTALL = YES;
804 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
805 | SWIFT_VERSION = 4.0;
806 | };
807 | name = Debug;
808 | };
809 | A039208E1E0F3A8B005A6E89 /* Release */ = {
810 | isa = XCBuildConfiguration;
811 | buildSettings = {
812 | CODE_SIGN_ENTITLEMENTS = "Generate.../Generate___.entitlements";
813 | CODE_SIGN_IDENTITY = "Mac Developer";
814 | COMBINE_HIDPI_IMAGES = YES;
815 | DEVELOPMENT_TEAM = 5C59L2E3AR;
816 | INFOPLIST_FILE = Generate.../Info.plist;
817 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks";
818 | MACOSX_DEPLOYMENT_TARGET = 10.11;
819 | PRODUCT_BUNDLE_IDENTIFIER = com.wangjie.CodeGenerator.Generate;
820 | PRODUCT_NAME = "$(TARGET_NAME)";
821 | PROVISIONING_PROFILE_SPECIFIER = "";
822 | SKIP_INSTALL = YES;
823 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
824 | SWIFT_VERSION = 4.0;
825 | };
826 | name = Release;
827 | };
828 | /* End XCBuildConfiguration section */
829 |
830 | /* Begin XCConfigurationList section */
831 | A03920541E0F3A7B005A6E89 /* Build configuration list for PBXProject "CodeGenerator" */ = {
832 | isa = XCConfigurationList;
833 | buildConfigurations = (
834 | A03920711E0F3A7B005A6E89 /* Debug */,
835 | A03920721E0F3A7B005A6E89 /* Release */,
836 | );
837 | defaultConfigurationIsVisible = 0;
838 | defaultConfigurationName = Release;
839 | };
840 | A03920731E0F3A7B005A6E89 /* Build configuration list for PBXNativeTarget "CodeGenerator" */ = {
841 | isa = XCConfigurationList;
842 | buildConfigurations = (
843 | A03920741E0F3A7B005A6E89 /* Debug */,
844 | A03920751E0F3A7B005A6E89 /* Release */,
845 | );
846 | defaultConfigurationIsVisible = 0;
847 | defaultConfigurationName = Release;
848 | };
849 | A03920761E0F3A7B005A6E89 /* Build configuration list for PBXNativeTarget "CodeGeneratorTests" */ = {
850 | isa = XCConfigurationList;
851 | buildConfigurations = (
852 | A03920771E0F3A7B005A6E89 /* Debug */,
853 | A03920781E0F3A7B005A6E89 /* Release */,
854 | );
855 | defaultConfigurationIsVisible = 0;
856 | defaultConfigurationName = Release;
857 | };
858 | A039208C1E0F3A8B005A6E89 /* Build configuration list for PBXNativeTarget "Generate..." */ = {
859 | isa = XCConfigurationList;
860 | buildConfigurations = (
861 | A039208D1E0F3A8B005A6E89 /* Debug */,
862 | A039208E1E0F3A8B005A6E89 /* Release */,
863 | );
864 | defaultConfigurationIsVisible = 0;
865 | defaultConfigurationName = Release;
866 | };
867 | /* End XCConfigurationList section */
868 | };
869 | rootObject = A03920511E0F3A7B005A6E89 /* Project object */;
870 | }
871 |
--------------------------------------------------------------------------------
/CodeGenerator/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
--------------------------------------------------------------------------------