├── .gitignore ├── CodeGenerator.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── CodeGenerator.xcscheme │ └── Generate....xcscheme ├── CodeGenerator ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ └── Main.storyboard ├── Info.plist └── ViewController.swift ├── CodeGeneratorTests ├── AccessLevelTests.swift ├── CodeGeneratorTests.swift ├── EquatableClazz.txt ├── EquatableGeneratorTests.swift ├── FuncMockTests.swift ├── FuncSignatureTests.swift ├── GeneratedEquals.txt ├── GeneratedHash.txt ├── GeneratedInit.txt ├── GeneratedNSCoder.txt ├── HashableGeneratorTest.swift ├── Info.plist ├── InitGeneratorTests.swift ├── InterfaceMockerTests.swift ├── InterfaceSignatureTests.swift ├── NSCodingGeneratorTest.swift ├── NSObject+file.swift ├── SwiftTypeTests.swift ├── VarSignatureTests.swift ├── funcMock.txt ├── interface1.txt └── interface1Mock.txt ├── Generate... ├── AccessLevel.swift ├── ClosureParamMocker.swift ├── ClosureType.swift ├── CodingGenerator.swift ├── EquatableGenerator.swift ├── FuncMocker.swift ├── FuncParam.swift ├── FuncSignature.swift ├── GenerateAfterVarCommand.swift ├── GenerateAsExtensionCommand.swift ├── GenerateCodingCommand.swift ├── GenerateEquatableCommand.swift ├── GenerateHashableCommand.swift ├── GenerateInitCommand.swift ├── GenerateMockCommand.swift ├── Generate___.entitlements ├── Generator.swift ├── HashableGenerator.swift ├── Info.plist ├── InitGenerator.swift ├── InterfaceDefinition.swift ├── InterfaceMocker.swift ├── InterfaceSignature.swift ├── ParamMocker.swift ├── ParamMockerFactory.swift ├── SelectableGeneratorCommand.swift ├── SourceEditorExtension.swift ├── SourceError.swift ├── String+regexr.swift ├── SwiftParamMocker.swift ├── SwiftType.swift ├── TypeParser.swift └── VarSignature.swift └── README.md /.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 | -------------------------------------------------------------------------------- /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.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | Default 509 | 510 | 511 | 512 | 513 | 514 | 515 | Left to Right 516 | 517 | 518 | 519 | 520 | 521 | 522 | Right to Left 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | Default 534 | 535 | 536 | 537 | 538 | 539 | 540 | Left to Right 541 | 542 | 543 | 544 | 545 | 546 | 547 | Right to Left 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /CodeGeneratorTests/EquatableClazz.txt: -------------------------------------------------------------------------------- 1 | class EquatableClazz { 2 | var var0: TimeInterval 3 | let var1: [String] 4 | var var2: Bool? 5 | } 6 | -------------------------------------------------------------------------------- /CodeGeneratorTests/EquatableGeneratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EquatableGeneratorTests.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 EquatableGeneratorTests: 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 testEquatableGenerator() { 25 | let source = string(from: "EquatableClazz", ofType: "txt") 26 | let interface = try! InterfaceSignature(interfaceSource: source, lines: source.components(separatedBy: "\n")) 27 | let equatableGenerator = EquatableGenerator(interfaceSignature: interface, indentation: " ") 28 | 29 | var expectedEqualsSource = string(from: "GeneratedEquals", ofType: "txt").components(separatedBy: "\n") 30 | expectedEqualsSource.removeLast() 31 | 32 | XCTAssertEqual(equatableGenerator.lines.count, expectedEqualsSource.count) 33 | let count = min(equatableGenerator.lines.count, expectedEqualsSource.count) 34 | for i in 0.. 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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /CodeGeneratorTests/HashableGeneratorTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HashableGeneratorTest.swift 3 | // CodeGenerator 4 | // 5 | // Created by WANG Jie on 02/01/2017. 6 | // Copyright © 2017 wangjie. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import CodeGenerator 11 | 12 | class HashableGeneratorTest: XCTestCase { 13 | override func setUp() { 14 | super.setUp() 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 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 testEquatableGenerator() { 24 | let source = string(from: "EquatableClazz", ofType: "txt") 25 | let interface = try! InterfaceSignature(interfaceSource: source, lines: source.components(separatedBy: "\n")) 26 | let hashableeGenerator = HashableGenerator(interfaceSignature: interface, indentation: " ") 27 | 28 | var expectedHashSource = string(from: "GeneratedHash", ofType: "txt").components(separatedBy: "\n") 29 | expectedHashSource.removeLast() 30 | 31 | XCTAssertEqual(hashableeGenerator.lines.count, expectedHashSource.count) 32 | let count = min(hashableeGenerator.lines.count, expectedHashSource.count) 33 | for i in 0.. 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 | -------------------------------------------------------------------------------- /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 "].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 | let path = Bundle(for: Swift.type(of: self)).path(forResource: path, ofType: type)! 15 | return try! String(contentsOfFile: path) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /CodeGeneratorTests/VarSignatureTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VarSignatureTests.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 VarSignatureTests: 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 testVar1() { 25 | let var1 = VarSignature(string: " var name: String?") 26 | XCTAssertEqual(var1, VarSignature(declaration: "var", name: "name", type: "String?")) 27 | } 28 | 29 | func testVar2() { 30 | let var2 = VarSignature(string: " let name: (String) -> 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.../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 | -------------------------------------------------------------------------------- /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.../ClosureType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ClosureType.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 ClosureType: SwiftType { 12 | 13 | override func name(with wrap: String) -> 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.../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 | -------------------------------------------------------------------------------- /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.../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.../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.../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 | -------------------------------------------------------------------------------- /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.../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.../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.../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.../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.../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.../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.../Generate___.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.../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.../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.../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 | -------------------------------------------------------------------------------- /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.../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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.../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 | -------------------------------------------------------------------------------- /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.../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.../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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.../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 | -------------------------------------------------------------------------------- /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 | ![alt tag](https://j.gifs.com/pgVEVr.gif) 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 | --------------------------------------------------------------------------------