Repository: onevcat/VVDocumenter-Xcode Branch: master Commit: 0ab09a930dbe Files: 72 Total size: 293.7 KB Directory structure: gitextract_6z6nzidj/ ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── VVDocumenter-Xcode/ │ ├── Commenter/ │ │ ├── VVArgument.h │ │ ├── VVArgument.m │ │ ├── VVBaseCommenter.h │ │ ├── VVBaseCommenter.m │ │ ├── VVCommenter.h │ │ ├── VVEnumCommenter.h │ │ ├── VVEnumCommenter.m │ │ ├── VVFunctionCommenter.h │ │ ├── VVFunctionCommenter.m │ │ ├── VVMacroCommenter.h │ │ ├── VVMacroCommenter.m │ │ ├── VVMethodCommenter.h │ │ ├── VVMethodCommenter.m │ │ ├── VVPropertyCommenter.h │ │ ├── VVPropertyCommenter.m │ │ ├── VVStructCommenter.h │ │ ├── VVStructCommenter.m │ │ ├── VVSwiftEnumCommenter.h │ │ ├── VVSwiftEnumCommenter.m │ │ ├── VVSwiftExtensionCommenter.h │ │ ├── VVSwiftExtensionCommenter.m │ │ ├── VVSwiftFunctionCommenter.h │ │ ├── VVSwiftFunctionCommenter.m │ │ ├── VVSwiftPropertyCommenter.h │ │ ├── VVSwiftPropertyCommenter.m │ │ ├── VVVariableCommenter.h │ │ └── VVVariableCommenter.m │ ├── KeyboardHelper/ │ │ ├── VVKeyboardEventSender.h │ │ └── VVKeyboardEventSender.m │ ├── OCCategory/ │ │ ├── NSString+PDRegex/ │ │ │ ├── NSString+PDRegex.h │ │ │ └── NSString+PDRegex.m │ │ ├── NSString+VVSyntax/ │ │ │ ├── NSString+VVSyntax.h │ │ │ └── NSString+VVSyntax.m │ │ ├── NSString+VVTextGetter/ │ │ │ ├── NSString+VVTextGetter.h │ │ │ └── NSString+VVTextGetter.m │ │ ├── NSTextView+VVTextGetter/ │ │ │ ├── NSTextView+VVTextGetter.h │ │ │ └── NSTextView+VVTextGetter.m │ │ ├── VVTextResult.h │ │ └── VVTextResult.m │ ├── ProjectHelper/ │ │ ├── VVProject.h │ │ ├── VVProject.m │ │ ├── VVWorkspaceManager.h │ │ └── VVWorkspaceManager.m │ ├── Setting/ │ │ ├── VVDSettingPanelWindowController.h │ │ ├── VVDSettingPanelWindowController.m │ │ ├── VVDSettingPanelWindowController.xib │ │ ├── VVDocumenterSetting.h │ │ └── VVDocumenterSetting.m │ ├── VVDocumenter-Xcode-Info.plist │ ├── VVDocumenter-Xcode-Prefix.pch │ ├── VVDocumenter.h │ ├── VVDocumenter.m │ ├── VVDocumenterManager.h │ ├── VVDocumenterManager.m │ └── en.lproj/ │ └── InfoPlist.strings ├── VVDocumenter-Xcode.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ ├── VVDocumenter-Xcode.xcscheme │ └── VVDocumenterTests.xcscheme └── VVDocumenterTests/ ├── CommenterTests/ │ └── CommenterTests.m ├── DocumenterTests/ │ └── VVMethodTestsCode.plist ├── SyntaxTests/ │ └── SyntaxTests.m ├── VVDocumenterTests-Info.plist ├── VVDocumenterTests-Prefix.pch ├── VVDocumenterTests.m ├── VVTestHelper.h ├── VVTestHelper.m └── en.lproj/ └── InfoPlist.strings ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ ######################### # .gitignore file for Xcode4 / OS X Source projects # # Version 2.1 # For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects # # 2013 updates: # - fixed the broken "save personal Schemes" # - added line-by-line explanations for EVERYTHING (some were missing) # # NB: if you are storing "built" products, this WILL NOT WORK, # and you should use a different .gitignore (or none at all) # This file is for SOURCE projects, where there are many extra # files that we want to exclude # ######################### ##### # OS X temporary files that should never be committed # # c.f. http://www.westwind.com/reference/os-x/invisibles.html .DS_Store # c.f. http://www.westwind.com/reference/os-x/invisibles.html .Trashes # c.f. http://www.westwind.com/reference/os-x/invisibles.html *.swp # *.lock - this is used and abused by many editors for many different things. # For the main ones I use (e.g. Eclipse), it should be excluded # from source-control, but YMMV *.lock # # profile - REMOVED temporarily (on double-checking, this seems incorrect; I can't find it in OS X docs?) #profile #### # Xcode temporary files that should never be committed # # NB: NIB/XIB files still exist even on Storyboard projects, so we want this... *~.nib #### # Xcode build files - # # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" DerivedData/ # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" build/ ##### # Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) # # This is complicated: # # SOMETIMES you need to put this file in version control. # Apple designed it poorly - if you use "custom executables", they are # saved in this file. # 99% of projects do NOT use those, so they do NOT want to version control this file. # ..but if you're in the 1%, comment out the line "*.pbxuser" # .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html *.pbxuser # .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html *.mode1v3 # .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html *.mode2v3 # .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file *.perspectivev3 # NB: also, whitelist the default ones, some projects need to use these !default.pbxuser !default.mode1v3 !default.mode2v3 !default.perspectivev3 #### # Xcode 4 - semi-personal settings # # # OPTION 1: --------------------------------- # throw away ALL personal settings (including custom schemes! # - unless they are "shared") # # NB: this is exclusive with OPTION 2 below xcuserdata # OPTION 2: --------------------------------- # get rid of ALL personal settings, but KEEP SOME OF THEM # - NB: you must manually uncomment the bits you want to keep # # NB: this *requires* git v1.8.2 or above; you may need to upgrade to latest OS X, # or manually install git over the top of the OS X version # NB: this is exclusive with OPTION 1 above # #xcuserdata/**/* # (requires option 2 above): Personal Schemes # #!xcuserdata/**/xcschemes/* #### # XCode 4 workspaces - more detailed # # Workspaces are important! They are a core feature of Xcode - don't exclude them :) # # Workspace layout is quite spammy. For reference: # # /(root)/ # /(project-name).xcodeproj/ # project.pbxproj # /project.xcworkspace/ # contents.xcworkspacedata # /xcuserdata/ # /(your name)/xcuserdatad/ # UserInterfaceState.xcuserstate # /xcsshareddata/ # /xcschemes/ # (shared scheme name).xcscheme # /xcuserdata/ # /(your name)/xcuserdatad/ # (private scheme).xcscheme # xcschememanagement.plist # # #### # Xcode 4 - Deprecated classes # # Allegedly, if you manually "deprecate" your classes, they get moved here. # # We're using source-control, so this is a "feature" that we do not want! *.moved-aside #### # UNKNOWN: recommended by others, but I can't discover what these files are # # ...none. Everything is now explained. /VVDocumenter-Xcode.xcodeproj/project.xcworkspace/xcshareddata/ .idea ================================================ FILE: .travis.yml ================================================ language: objective-c xcode_project: VVDocumenter-Xcode.xcodeproj xcode_scheme: VVDocumenter-Xcode ================================================ FILE: LICENSE ================================================ Copyright (c) 2015 Wei Wang Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # VVDocumenter-Xcode [![Build Status](https://api.travis-ci.org/onevcat/VVDocumenter-Xcode.svg)](https://travis-ci.org/onevcat/VVDocumenter-Xcode) Flattr this --- # Goodbye World In Xcode 8, Apple integrated a comment documentation generator plugin, which is built on top of VVDocumenter. Now this project is proud to be a part of Apple. It means you could just use the shortcut (⌥ Option + ⌘ Command + /) to add a documentation comment to your code if you are using Xcode 8 or above! VVDocumenter is one of my hobby projects [from 2013](https://github.com/onevcat/VVDocumenter-Xcode/commit/6a2b604713c9fb573e229daece8286dac68ac24a), back to the age of Xcode 4. It serves well for these years and I am so glad that it helps a lot of developers to improve their productivity. Since there is no need to install this plugin anymore, the development of VVDocumenter will not continue. Yes, it's time to say goodbye, with a happy ending. Thank you all for your selfless support to this project. Let's build more great things and make the world better in future! ## What is this? Writing documentation is so important for developing, but it is really painful with Xcode. Think about how much time you are wasting in pressing '*' or '/', and typing the parameters again and again. Now, you can find the method (or any code) you want to document to, and type in `///`, the document will be generated for you and all params and return will be extracted into a Javadoc style, which is compatible with [appledoc](https://github.com/tomaz/appledoc), [Doxygen](http://www.stack.nl/~dimitri/doxygen/) and [HeaderDoc](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/HeaderDoc/intro/intro.html). You can just fill the inline placeholder tokens to finish your document. Here is an image which can show what it exactly does. ![Screenshot](https://raw.github.com/onevcat/VVDocumenter-Xcode/master/ScreenShot.gif) > By the way, it also supports [Swift](https://developer.apple.com/swift/) now. Cheers! ![Screenshot](https://raw.github.com/onevcat/VVDocumenter-Xcode/master/vvdocumenter-swift.gif) ## How to install and use? The best way of installing is by [Alcatraz](http://alcatraz.io). Install Alcatraz followed by the instruction, restart your Xcode and press `⇧⌘9`. You can find `VVDocumenter-Xcode` in the list and click the icon on left to install. If you do not like the Alcatraz way, you can also clone the repo. Then build the `VVDocumenter-Xcode` target in the Xcode project and the plug-in will automatically be installed in `~/Library/Application Support/Developer/Shared/Xcode/Plug-ins`. Relaunch Xcode and type in `///` above any code you want to write a document to. If you want to use other text beside of `///` to trigger the document insertion, you can find a setting panel by clicking `VVDocument` in the Window menu of Xcode. You can also find some other useful options there, including setting using spaces instead of tab in the panel or changing the format of generated documentation. ## Xcode version? This plug-in is supported in Xcode 5, 6 and 7. From Xcode 5, Apple added a UUID-verification to all plugins to ensure the stability when Xcode gets updated. The value of `DVTPlugInCompatibilityUUIDs` in project plist should contains current UUID of Xcode version, or the plugin does not work. And from Xcode 6.3, you will be prompt to "Load third party bundle" if you are using a plugin. You should always select "Load bundles" to enable this plugin. All plugins will be disabled once you update your Xcode, since the supported UUIDs in the plugins do not contain the one. You should try to clean your plugins folder (`~/Library/Application Support/Developer/Shared/Xcode/Plug-ins` by default) and clone/build the latest version from master branch. If you happened to skip the bundle loading, you can use this to reset the prompt: ```bash defaults delete com.apple.dt.Xcode DVTPlugInManagerNonApplePlugIns-Xcode-{your_xcode_version} ``` **Please do not open an issue if this plugin not work in your newly updated Xcode.** Pull request for new `DVTPlugInCompatibilityUUIDs` is welcome, and if UUID of your Xcode version is already there, please try to reinstall the plugin from a clean state. The default deployment target is 10.8. If you want to use it in a earlier OS version, you should change OS X Deployment Target (in project info setting) to your system version. ## Swift Support Yes, this plugin supports documentation for Swift 2 now. Check [this post](http://ericasadun.com/2015/06/14/swift-header-documentation-in-xcode-7/) to see how to write the documentation for swift. By using `VVDocumenter-Xcode`, you can just type `///` to make the magic happen. The documentation format changed from Swift 1.x to 2. If you are using Swift 1.x, you could build from branch [Xcode6](https://github.com/onevcat/VVDocumenter-Xcode/tree/Xcode6) to get the support for the earlier format. ## Limitations and Future The plugin is using simulation of keyboard event to insert the doc comments for you. So it is depending the keyboard shortcut of Xcode. These two kinds of operation are being used: * Delete to Beginning of the Line (⌘⌫) * Paste (⌘V) If you have modified these two shortcuts in your Xcode, the newset version of the plugin would not work correctly. Instead, you can use a earlier version such as [this one(commit 03c4169ff7)](https://github.com/onevcat/VVDocumenter-Xcode/tree/03c4169ff79b618b9fd3db93dd96652a522ad3e0). Be causion you may suffer an [undo and redo issue ](https://github.com/onevcat/VVDocumenter-Xcode/issues/3). `VVDocumenter-Xcode` is now using regular expression to extract things needed, which is not the best way to do such thing. A better approach could be using the AST, and I also have a plan to do it later if I have some more time :) ## License VVDocumenter is published under MIT License. See the LICENSE file for more. ================================================ FILE: VVDocumenter-Xcode/Commenter/VVArgument.h ================================================ // // Argument.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-19. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import @interface VVArgument : NSObject @property (nonatomic, copy) NSString *type; @property (nonatomic, copy) NSString *name; @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVArgument.m ================================================ // // Argument.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-19. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVArgument.h" @implementation VVArgument -(void)setType:(NSString *)type { if (type != _type) { _type = [[[type vv_stringByReplacingRegexPattern:@"&$" withString:@""] vv_stringByReplacingRegexPattern:@"\\s*\\*$" withString:@""] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; } } -(void)setName:(NSString *)name { if (name != _name) { _name = [[[[[[[name vv_stringByReplacingRegexPattern:@"\\(|\\)" withString:@""] vv_stringByReplacingRegexPattern:@"^&" withString:@""] vv_stringByReplacingRegexPattern:@"^\\*+" withString:@""] vv_stringByReplacingRegexPattern:@"\\[.*$" withString:@""] vv_stringByReplacingRegexPattern:@",$" withString:@""] vv_stringByReplacingRegexPattern:@";$" withString:@""] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; } } - (NSString *)description { return [NSString stringWithFormat:@"%@< type: %@, name: %@>", self.class, self.type, self.name]; } - (BOOL)isEqual:(id)other { if (other == self) { return YES; } if ([other isKindOfClass:self.class]) { return [((VVArgument *)other).type isEqualToString:self.type] && [((VVArgument *)other).name isEqualToString:self.name]; } return NO; } @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVBaseCommenter.h ================================================ // // VVBaseCommenter.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import @interface VVBaseCommenter : NSObject @property (nonatomic, copy) NSString *indent; @property (nonatomic, copy) NSString *code; @property (nonatomic, strong) NSMutableArray *arguments; @property (nonatomic, assign) BOOL hasReturn; @property (nonatomic, assign) BOOL hasThrows; -(instancetype) initWithIndentString:(NSString *)indent codeString:(NSString *)code; -(NSString *) document; -(NSString *) documentForC; -(NSString *) documentForSwift; -(NSString *) documentForSwiftEnum; -(void) parseArgumentsInputArgs:(NSString *)rawArgsCode; -(BOOL) shouldComment; // Comment methods -(NSString *) startComment; -(NSString *) startCommentWithDescriptionTag:(NSString *)tag; -(NSString *) argumentsComment; -(NSString *) endComment; -(NSString *) returnComment; -(NSString *) sinceComment; @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVBaseCommenter.m ================================================ // // VVBaseCommenter.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVBaseCommenter.h" #import "VVArgument.h" #import "VVDocumenterSetting.h" #import "NSString+VVSyntax.h" #import "VVProject.h" @interface VVBaseCommenter() @property (nonatomic, copy) NSString *space; @property (nonatomic, assign) BOOL forSwift; @property (nonatomic, assign) BOOL forSwiftEnum; @end @implementation VVBaseCommenter -(instancetype) initWithIndentString:(NSString *)indent codeString:(NSString *)code { self = [super init]; if (self) { _indent = indent; _code = code; _arguments = [NSMutableArray array]; _space = [[VVDocumenterSetting defaultSetting] spacesString]; _forSwift = NO; _forSwiftEnum = NO; } return self; } -(NSString *) paramSymbol { return self.forSwift ? @"- parameter" : @"@param"; } -(NSString *) returnSymbol { return self.forSwift ? @"- returns:" : @"@return"; } -(NSString *) throwsSymbol { return @"- throws:"; } -(NSString *) startCommentWithDescriptionTag:(NSString *)tag { NSString *authorInfo = @""; NSString *dateInfo = @""; if ([[VVDocumenterSetting defaultSetting] useAuthorInformation]) { NSMutableString *authorCotent = @"".mutableCopy; if ([[VVDocumenterSetting defaultSetting] authorInformation].length > 0) { [authorCotent appendString:[[VVDocumenterSetting defaultSetting] authorInformation]]; } if ([[VVDocumenterSetting defaultSetting] useDateInformation]) { NSString *formatString = [[VVDocumenterSetting defaultSetting] dateInformationFormat]; if ([formatString length] <= 0) { formatString = @"MM-dd-YYYY HH:MM:ss"; } NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:formatString]; dateInfo = [formatter stringFromDate:[NSDate date]]; if (self.forSwift) { [authorCotent appendString: [NSString stringWithFormat:@"\n%@- date: %@", self.prefixString, dateInfo]]; } else { if (authorCotent.length > 0) { [authorCotent appendString:@", "]; } [authorCotent appendString: dateInfo]; } } if (self.forSwift) { authorInfo = [NSString stringWithFormat:@"\n%@- author: %@\n", self.prefixString, authorCotent]; } else { authorInfo = [NSString stringWithFormat:@"%@@author %@\n%@\n", self.prefixString, authorCotent, self.prefixString]; } } if ([[VVDocumenterSetting defaultSetting] useHeaderDoc]) { return [NSString stringWithFormat:@"%@/*!\n%@%@%@<#Description#>\n", self.indent, authorInfo, self.prefixString, tag]; } else if ([[VVDocumenterSetting defaultSetting] prefixWithSlashes]) { return [NSString stringWithFormat:@"%@%@%@<#Description#>\n", self.prefixString, authorInfo, tag]; } else { if (self.forSwift){ return [NSString stringWithFormat:@"%@/**\n%@%@<#Description#>\n%@", self.indent, self.prefixString, tag, authorInfo]; } else { return [NSString stringWithFormat:@"%@/**\n%@%@%@<#Description#>\n", self.indent, authorInfo, self.prefixString, tag]; } } } -(NSString *) startComment { NSString *descriptionTag = [[VVDocumenterSetting defaultSetting] briefDescription] && !self.forSwift ? @"@brief " : @""; return [self startCommentWithDescriptionTag:descriptionTag]; } -(NSString *) argumentsComment { if (self.arguments.count == 0) return @""; // start off with an empty line NSMutableString *result = [NSMutableString stringWithFormat:@"%@", self.emptyLine]; int longestNameLength = [[self.arguments valueForKeyPath:@"@max.name.length"] intValue]; BOOL useSpace = [[VVDocumenterSetting defaultSetting] useSpaces]; for (VVArgument *arg in self.arguments) { NSString *name = arg.name; if ([[VVDocumenterSetting defaultSetting] alignArgumentComments]) { if (self.forSwiftEnum) { if (useSpace) { name = [[name stringByAppendingString:@":"] stringByPaddingToLength:longestNameLength + 1 withString:@" " startingAtIndex:0]; } else { NSInteger tabSpaceRateCount = [[VVDocumenterSetting defaultSetting] spaceCount]; NSInteger neededTabCount = (longestNameLength + tabSpaceRateCount - name.length) / tabSpaceRateCount - 1; name = [[name stringByAppendingString:@":"] stringByPaddingToLength:(name.length + 1 + neededTabCount) withString:@"\t" startingAtIndex:0]; } } else { if (self.forSwift) { name = [name stringByAppendingString:@":"]; if (useSpace) { name = [name stringByPaddingToLength:longestNameLength + 1 withString:@" " startingAtIndex:0]; } else { NSInteger tabSpaceRateCount = [[VVDocumenterSetting defaultSetting] spaceCount]; NSInteger neededTabCount = (longestNameLength + 1 + tabSpaceRateCount - name.length) / tabSpaceRateCount - 1; name = [name stringByPaddingToLength:(name.length + neededTabCount) withString:@"\t" startingAtIndex:0]; } } else { if (useSpace) { name = [name stringByPaddingToLength:longestNameLength withString:@" " startingAtIndex:0]; } else { NSInteger tabSpaceRateCount = [[VVDocumenterSetting defaultSetting] spaceCount]; NSInteger neededTabCount = (longestNameLength + tabSpaceRateCount - name.length) / tabSpaceRateCount - 1; name = [name stringByPaddingToLength:(name.length + neededTabCount) withString:@"\t" startingAtIndex:0]; } } } } else { if (self.forSwiftEnum || self.forSwift) { name = [name stringByAppendingString:@":"]; } } NSString *indentString = useSpace ? @" " : @"\t"; if (self.forSwiftEnum) { [result appendFormat:@"%@- %@%@<#%@ description#>\n", self.prefixString, name, indentString, arg.name]; } else { [result appendFormat:@"%@%@ %@%@<#%@ description#>\n", self.prefixString, [self paramSymbol], name, indentString, arg.name]; } } return result; } -(NSString *) returnComment { if (!self.hasReturn) { return @""; } else { return [NSString stringWithFormat:@"%@%@%@ <#return value description#>\n", self.emptyLine, self.prefixString, [self returnSymbol]]; } } -(NSString *) throwsComment { if (!self.hasThrows) { return @""; } else { return [NSString stringWithFormat:@"%@%@%@ <#throws value description#>\n", self.emptyLine, self.prefixString, [self throwsSymbol]]; } } -(NSString *) sinceComment { //It seems no since attribute for swift? Maybe I am wrong. VVProject *project = [VVProject projectForKeyWindow]; if (!self.forSwift && [[VVDocumenterSetting defaultSetting] addSinceToComments]) { VVDSinceOption sinceOption = [[VVDocumenterSetting defaultSetting] sinceOption]; switch (sinceOption) { case VVDSinceOptionPlaceholder: { return [NSString stringWithFormat:@"%@%@@since <#version number#>\n", self.emptyLine, self.prefixString]; break; } case VVDSinceOptionProjectVersion: { if (project.projectVersion && project.projectVersion.length>0) { return [NSString stringWithFormat:@"%@%@@since <#%@#>\n", self.emptyLine, self.prefixString,project.projectVersion]; }else{ // Fall back onto default placeholder if no project version can be obtained. return [NSString stringWithFormat:@"%@%@@since <#version number#>\n", self.emptyLine, self.prefixString]; } break; } case VVDSinceOptionSpecificVersion: { NSString *version = [[VVDocumenterSetting defaultSetting] sinceVersion]; if (version && version.length>0) { return [NSString stringWithFormat:@"%@%@@since <#%@#>\n", self.emptyLine, self.prefixString, version]; }else{ // Fall back onto default placeholder if no version can be obtained. return [NSString stringWithFormat:@"%@%@@since <#version number#>\n", self.emptyLine, self.prefixString]; } break; } } } else { return @""; } } -(NSString *) endComment { if ([[VVDocumenterSetting defaultSetting] prefixWithSlashes]) { return @""; } else { return [NSString stringWithFormat:@"%@ */",self.indent]; } } -(NSString *) documentForSwift { self.forSwift = YES; return [self __document]; } -(NSString *) documentForSwiftEnum { self.forSwiftEnum = YES; self.forSwift = YES; return [self __document]; } -(NSString *) documentForC { self.forSwift = NO; return [self __document]; } -(NSString *) __document { NSString * comment = [NSString stringWithFormat:@"%@%@%@%@%@%@", [self startComment], [self argumentsComment], [self throwsComment], [self returnComment], [self sinceComment], [self endComment]]; // The last line of the comment should be adjacent to the next line of code, // back off the newline from the last comment component. if ([[VVDocumenterSetting defaultSetting] prefixWithSlashes]) { return [comment stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; } else { return comment; } } -(NSString *) document { //This is the default action return [self documentForC]; } -(NSString *) emptyLine { if ([[VVDocumenterSetting defaultSetting] blankLinesBetweenSections]) { return [[NSString stringWithFormat:@"%@\n", self.prefixString] vv_stringByTrimEndSpaces]; } else { return @""; } } -(NSString *) prefixString { if ([[VVDocumenterSetting defaultSetting] prefixWithStar] && !self.forSwift) { return [NSString stringWithFormat:@"%@ *%@", self.indent, self.space]; } else if ([[VVDocumenterSetting defaultSetting] prefixWithSlashes]) { return [NSString stringWithFormat:@"%@///%@", self.indent, self.space]; } else { return [NSString stringWithFormat:@"%@ ", self.indent]; } } -(void) parseArgumentsInputArgs:(NSString *)rawArgsCode { [self.arguments removeAllObjects]; if (rawArgsCode.length == 0) { return; } NSArray *argumentStrings = [rawArgsCode componentsSeparatedByString:@","]; for (__strong NSString *argumentString in argumentStrings) { VVArgument *arg = [[VVArgument alloc] init]; argumentString = [argumentString vv_stringByReplacingRegexPattern:@"=\\s*\\w*" withString:@""]; argumentString = [argumentString vv_stringByReplacingRegexPattern:@"\\(" withString:@" "]; argumentString = [argumentString vv_stringByReplacingRegexPattern:@"\\*" withString:@" "]; argumentString = [argumentString vv_stringByReplacingRegexPattern:@"\\s+$" withString:@""]; argumentString = [argumentString vv_stringByReplacingRegexPattern:@"\\s+" withString:@" "]; NSMutableArray *tempArgs = [[argumentString componentsSeparatedByString:@" "] mutableCopy]; while ([[tempArgs lastObject] isEqualToString:@" "]) { [tempArgs removeLastObject]; } arg.name = [tempArgs lastObject]; [tempArgs removeLastObject]; arg.type = [tempArgs componentsJoinedByString:@" "]; VVLog(@"arg type: %@", arg.type); VVLog(@"arg name: %@", arg.name); [self.arguments addObject:arg]; } } -(BOOL) shouldComment { return YES; } @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVCommenter.h ================================================ // // VVCommenter.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-18. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #ifndef CommentTest_Commenter_h #define CommentTest_Commenter_h #import "VVBaseCommenter.h" #import "VVMethodCommenter.h" #import "VVPropertyCommenter.h" #import "VVFunctionCommenter.h" #import "VVMacroCommenter.h" #import "VVEnumCommenter.h" #import "VVStructCommenter.h" #import "VVVariableCommenter.h" #import "VVArgument.h" #import "VVSwiftFunctionCommenter.h" #import "VVSwiftEnumCommenter.h" #import "VVSwiftPropertyCommenter.h" #import "VVSwiftExtensionCommenter.h" #endif ================================================ FILE: VVDocumenter-Xcode/Commenter/VVEnumCommenter.h ================================================ // // VVEnumCommenter.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVBaseCommenter.h" @interface VVEnumCommenter : VVBaseCommenter @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVEnumCommenter.m ================================================ // // VVEnumCommenter.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVEnumCommenter.h" @implementation VVEnumCommenter - (NSString *)document { //Regular comment documentation NSString *finalString = [NSString stringWithFormat:@"%@%@%@", [self startComment], [self sinceComment], [self endComment]]; if (![finalString hasSuffix:@"\n"]) { finalString = [finalString stringByAppendingString:@"\n"]; } // Grab everything from the start of the line to the opening brace, which // may be on a different line. NSString *enumDefinePattern = @"^\\s*(\\w+\\s+)?NS_(ENUM|OPTIONS)[\\s\\S]*?\\{"; NSRegularExpression *enumDefineExpression = [NSRegularExpression regularExpressionWithPattern:enumDefinePattern options:0 error:nil]; NSTextCheckingResult *enumDefineResult = [enumDefineExpression firstMatchInString:self.code options:0 range:NSMakeRange(0, self.code.length)]; finalString = [finalString stringByAppendingString:[self.code substringWithRange:[enumDefineResult rangeAtIndex:0]]]; finalString = [finalString substringToIndex:finalString.length - 1]; finalString = [finalString stringByAppendingString:@" {\n"]; NSString *endPattern = @"\\}\\s*;"; NSString *enumPartsString = [[self.code vv_stringByReplacingRegexPattern:enumDefinePattern withString:@""] vv_stringByReplacingRegexPattern:endPattern withString:@""]; NSArray *enumParts = [enumPartsString componentsSeparatedByString:@","]; for (NSString *part in enumParts) { NSString *trimmedPart = [part stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; //Only append when there is a enum define. (In case of the last comma, followed no define) if (trimmedPart.length != 0) { NSString *temp = [NSString stringWithFormat:@"%@%@%@", [self startCommentWithDescriptionTag:@""], [self sinceComment], [self endComment]]; if ([temp hasSuffix:@"\n"]) { // comment has a newline suffix, so trimmedPart will go on // the next line temp = [temp stringByAppendingString:trimmedPart]; } else { // comment does not have a newline suffix, so trimmedPart // needs to be moved to the next line temp = [temp stringByAppendingFormat:@"\n%@", trimmedPart]; } if (part != [enumParts lastObject]) { temp = [temp stringByAppendingString:@",\n"]; } else { // since trimmedPart was used there is no trailing newline temp = [temp stringByAppendingString:@"\n"]; } finalString = [finalString stringByAppendingString:temp]; } } return [finalString stringByAppendingString:@"};"]; } @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVFunctionCommenter.h ================================================ // // VVFunctionCommenter.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVBaseCommenter.h" @interface VVFunctionCommenter : VVBaseCommenter @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVFunctionCommenter.m ================================================ // // VVFunctionCommenter.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVFunctionCommenter.h" #import "VVArgument.h" @implementation VVFunctionCommenter -(void) captureReturnType { NSArray *arr = [self.code componentsSeparatedByString:@"("]; if (arr.count > 0 && (![arr[0] vv_matchesPatternRegexPattern:@"^\\s*void\\s*[^*]*\\s*\\w+$"] && ![arr[0] vv_matchesPatternRegexPattern:@"^\\w+\\svoid"])) { self.hasReturn = YES; } } -(void) captureParameters { NSArray * braceGroups = [self.code vv_stringsByExtractingGroupsUsingRegexPattern:@"\\(([^\\^].*?)\\)(?:__attribute__\\(\\(.*\\)\\))?"]; if (braceGroups.count > 0) { [self parseArgumentsInputArgs:braceGroups[0]]; } //Remove void arg in block NSArray *tempArray = [NSArray arrayWithArray:self.arguments]; [tempArray enumerateObjectsUsingBlock:^(VVArgument *arg, NSUInteger idx, BOOL *stop) { if ([arg.type isEqualToString:@""] && [arg.name isEqualToString:@"void"]) { [self.arguments removeObject:arg]; } }]; } -(NSString *) document { [self captureReturnType]; [self captureParameters]; return [super documentForC]; } @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVMacroCommenter.h ================================================ // // VVMacroCommenter.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVBaseCommenter.h" @interface VVMacroCommenter : VVBaseCommenter @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVMacroCommenter.m ================================================ // // VVMacroCommenter.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVMacroCommenter.h" @implementation VVMacroCommenter -(void) captureReturnType { self.hasReturn = YES; } -(void) captureParameters { NSArray * braceGroups = [self.code vv_stringsByExtractingGroupsUsingRegexPattern:@"\\(([^\\^][^\\(\\)]*)\\)"]; if (braceGroups.count > 0) { [self parseArgumentsInputArgs:braceGroups[0]]; } } -(NSString *) document { [self captureReturnType]; [self captureParameters]; return [super documentForC]; } @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVMethodCommenter.h ================================================ // // VVMethodCommenter.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVBaseCommenter.h" @interface VVMethodCommenter : VVBaseCommenter @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVMethodCommenter.m ================================================ // // VVMethodCommenter.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVMethodCommenter.h" #import "VVArgument.h" @implementation VVMethodCommenter -(void) captureReturnType { NSArray * matchedTypes = [self.code vv_stringsByExtractingGroupsUsingRegexPattern:@"^\\s*[+-]\\s*\\(([^\\(\\)]*)\\)"]; if (matchedTypes.count == 1) { if (![matchedTypes[0] vv_matchesPatternRegexPattern:@"^\\s*void\\s*[^*]*\\s*$"] && ![matchedTypes[0] vv_matchesPatternRegexPattern:@"^\\s*IBAction\\s*$"]) { self.hasReturn = YES; } } } -(void) captureParameters { NSArray * matchedParams = [self.code vv_stringsByExtractingGroupsUsingRegexPattern:@"\\:\\(([^:]+)\\)(\\w+)"]; VVLog(@"matchedParams: %@",matchedParams); for (int i = 0; i < (int)matchedParams.count - 1; i = i + 2) { VVArgument *arg = [[VVArgument alloc] init]; arg.type = [matchedParams[i] vv_stringByReplacingRegexPattern:@"[\\s*;.*]" withString:@""]; arg.name = [matchedParams[i + 1] vv_stringByReplacingRegexPattern:@"[\\s*;.*]" withString:@""]; [self.arguments addObject:arg]; } } -(NSString *) document { [self captureReturnType]; [self captureParameters]; return [super documentForC]; } @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVPropertyCommenter.h ================================================ // // VVPropertyCommenter.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVBaseCommenter.h" @interface VVPropertyCommenter : VVBaseCommenter @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVPropertyCommenter.m ================================================ // // VVPropertyCommenter.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVPropertyCommenter.h" @implementation VVPropertyCommenter @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVStructCommenter.h ================================================ // // VVStructCommenter.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVBaseCommenter.h" @interface VVStructCommenter : VVBaseCommenter @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVStructCommenter.m ================================================ // // VVStructCommenter.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVStructCommenter.h" @implementation VVStructCommenter @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVSwiftEnumCommenter.h ================================================ // // VVSwiftEnumCommenter.h // VVDocumenter-Xcode // // Created by 王 巍 on 14-7-30. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVBaseCommenter.h" @interface VVSwiftEnumCommenter : VVBaseCommenter @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVSwiftEnumCommenter.m ================================================ // // VVSwiftEnumCommenter.m // VVDocumenter-Xcode // // Created by 王 巍 on 14-7-30. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVSwiftEnumCommenter.h" #import "VVArgument.h" @implementation VVSwiftEnumCommenter -(void) captureParameters { NSString *normalizedCode = [self.code vv_stringByReplacingRegexPattern:@"\\s*\\n\\s*" withString:@"\n"]; NSArray *lines = [normalizedCode componentsSeparatedByString:@"\n"]; [lines enumerateObjectsUsingBlock:^(NSString *line, NSUInteger idx, BOOL *stop) { if ([line vv_matchesPatternRegexPattern:@"^case\\s+"]) { NSString * plainCase = [line vv_stringByReplacingRegexPattern:@"\\(.*?\\)" withString:@""]; plainCase = [[plainCase vv_stringByReplacingRegexPattern:@"^case\\s+" withString:@""] vv_stringByReplacingRegexPattern:@"\\s+" withString:@""]; NSArray *cases = [plainCase componentsSeparatedByString:@","]; [cases enumerateObjectsUsingBlock:^(NSString *name, NSUInteger idx, BOOL *stop) { NSString *plainName = [name vv_stringByReplacingRegexPattern:@"=\\s*.*$" withString:@""]; if ([plainName hasPrefix:@"."]) { return; } VVArgument *arg = [[VVArgument alloc] init]; arg.name = plainName; [self.arguments addObject:arg]; }]; } }]; } -(NSString *) document { [self captureParameters]; return [super documentForSwiftEnum]; } @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVSwiftExtensionCommenter.h ================================================ // // VVSwiftExtensionCommenter.h // VVDocumenter-Xcode // // Created by WANG WEI on 2015/06/17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVBaseCommenter.h" @interface VVSwiftExtensionCommenter : VVBaseCommenter @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVSwiftExtensionCommenter.m ================================================ // // VVSwiftExtensionCommenter.m // VVDocumenter-Xcode // // Created by WANG WEI on 2015/06/17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVSwiftExtensionCommenter.h" @implementation VVSwiftExtensionCommenter -(NSString *) document { NSArray *component = [[self.code stringByReplacingOccurrencesOfString:@"{" withString:@""] componentsSeparatedByString:@":"]; NSString *description = @"Description"; if (component.count == 2) { description = [component.lastObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; } return [NSString stringWithFormat:@"// MARK: - <#%@#>", description]; } @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVSwiftFunctionCommenter.h ================================================ // // VVSwiftFunctionCommenter.h // VVDocumenter-Xcode // // Created by 王 巍 on 14-7-30. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVBaseCommenter.h" @interface VVSwiftFunctionCommenter : VVBaseCommenter @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVSwiftFunctionCommenter.m ================================================ // // VVSwiftFunctionCommenter.m // VVDocumenter-Xcode // // Created by 王 巍 on 14-7-30. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVSwiftFunctionCommenter.h" #import "VVArgument.h" #import "NSString+VVTextGetter.h" #import "VVTextResult.h" @implementation VVSwiftFunctionCommenter -(void) captureReturnType { VVTextResult *funcParenthesesResult = [self.code vv_textResultMatchPartWithPairOpenString:@"(" closeString:@")" currentLocation:0]; NSString * funcSignatureWithoutParams = [self.code stringByReplacingCharactersInRange:funcParenthesesResult.range withString:@" "]; if ([funcSignatureWithoutParams vv_matchesPatternRegexPattern:@"\\s+(throws|rethrows)\\s+"]) { self.hasThrows = YES; } if ([funcSignatureWithoutParams vv_matchesPatternRegexPattern:@"\\s*->\\s*\\(?(\\Void?|\\(\\s*\\))\\)?\\s*[{]"]) { self.hasReturn = NO; } else if ([funcSignatureWithoutParams vv_matchesPatternRegexPattern:@"s*->\\s*"]) { self.hasReturn = YES; } else if ([funcSignatureWithoutParams vv_matchesPatternRegexPattern:@"^\\s*(.*\\s+)?(init|subscript)\\s*"]) { self.hasReturn = YES; } else { self.hasReturn = NO; } } -(void) captureParameters { VVTextResult *funcParenthesesResult = [self.code vv_textResultMatchPartWithPairOpenString:@"(" closeString:@")" currentLocation:0]; NSArray * braceGroups = [funcParenthesesResult.string vv_stringsByExtractingGroupsUsingRegexPattern:@"\\((.*)\\)"]; if (braceGroups.count > 0) { NSString *content = braceGroups[0]; NSString *trimmed = [content stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; if (trimmed.length != 0) { [self parseSwiftArgumentsInputArgs:trimmed]; } } } -(void) parseSwiftArgumentsInputArgs:(NSString *)rawArgsCode { [self.arguments removeAllObjects]; if (rawArgsCode.length == 0) { return; } NSString *removedUnwantComma = [rawArgsCode vv_stringByReplacingRegexPattern:@"[{].*?[^}],.*?[)}]" withString:@""]; NSString *removedUnwantParentheses = [removedUnwantComma copy]; VVTextResult *parenthesesInParam = [removedUnwantComma vv_textResultMatchPartWithPairOpenString:@"(" closeString:@")" currentLocation:0]; while (parenthesesInParam.string) { removedUnwantParentheses = [removedUnwantParentheses stringByReplacingOccurrencesOfString:parenthesesInParam.string withString:@""]; parenthesesInParam = [removedUnwantParentheses vv_textResultMatchPartWithPairOpenString:@"(" closeString:@")" currentLocation:0]; } NSArray *argumentStrings = [removedUnwantParentheses componentsSeparatedByString:@","]; for (__strong NSString *argumentString in argumentStrings) { VVArgument *arg = [[VVArgument alloc] init]; argumentString = [argumentString vv_stringByReplacingRegexPattern:@"=\\s*\\w*" withString:@""]; argumentString = [argumentString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; argumentString = [argumentString vv_stringByReplacingRegexPattern:@"\\s+" withString:@" "]; NSMutableArray *tempArgs = [[argumentString componentsSeparatedByString:@":"] mutableCopy]; if (tempArgs.count == 1) { //There is no ":", it is not a arg continue; } NSString *firstPart = [[tempArgs firstObject] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; if ([firstPart rangeOfString:@" "].location != NSNotFound) { arg.name = [[[firstPart componentsSeparatedByString:@" "] lastObject] vv_stringByReplacingRegexPattern:@"#" withString:@""]; } else { arg.name = [firstPart vv_stringByReplacingRegexPattern:@"#" withString:@""]; } VVLog(@"arg name: %@", arg.name); [self.arguments addObject:arg]; } } -(NSString *) document { [self captureReturnType]; [self captureParameters]; return [super documentForSwift]; } @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVSwiftPropertyCommenter.h ================================================ // // VVSwiftPropertyCommenter.h // VVDocumenter-Xcode // // Created by 王 巍 on 14-7-31. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVBaseCommenter.h" @interface VVSwiftPropertyCommenter : VVBaseCommenter @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVSwiftPropertyCommenter.m ================================================ // // VVSwiftPropertyCommenter.m // VVDocumenter-Xcode // // Created by 王 巍 on 14-7-31. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVSwiftPropertyCommenter.h" @implementation VVSwiftPropertyCommenter -(NSString *) document { return [NSString stringWithFormat:@"/// <#Description#>"]; } @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVVariableCommenter.h ================================================ // // VVVariableCommenter.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVBaseCommenter.h" @interface VVVariableCommenter : VVBaseCommenter @end ================================================ FILE: VVDocumenter-Xcode/Commenter/VVVariableCommenter.m ================================================ // // VVVariableCommenter.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE./ #import "VVVariableCommenter.h" @implementation VVVariableCommenter @end ================================================ FILE: VVDocumenter-Xcode/KeyboardHelper/VVKeyboardEventSender.h ================================================ // // VVKeyboardEventSender.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-26. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import @interface VVKeyboardEventSender : NSObject -(void) beginKeyBoradEvents; -(void) sendKeyCode:(NSInteger)keyCode; -(void) sendKeyCode:(NSInteger)keyCode withModifierCommand:(BOOL)command alt:(BOOL)alt shift:(BOOL)shift control:(BOOL)control; -(void) sendKeyCode:(NSInteger)keyCode withModifier:(NSInteger)modifierMask; -(void) endKeyBoradEvents; @end ================================================ FILE: VVDocumenter-Xcode/KeyboardHelper/VVKeyboardEventSender.m ================================================ // // VVKeyboardEventSender.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-26. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVKeyboardEventSender.h" @interface VVKeyboardEventSender() { CGEventSourceRef _source; CGEventTapLocation _location; } @end @implementation VVKeyboardEventSender -(void) beginKeyBoradEvents { _source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState); _location = kCGHIDEventTap; } -(void) sendKeyCode:(NSInteger)keyCode { [self sendKeyCode:keyCode withModifier:0]; } -(void) sendKeyCode:(NSInteger)keyCode withModifierCommand:(BOOL)command alt:(BOOL)alt shift:(BOOL)shift control:(BOOL)control { NSInteger modifier = 0; if (command) { modifier = modifier ^ kCGEventFlagMaskCommand; } if (alt) { modifier = modifier ^ kCGEventFlagMaskAlternate; } if (shift) { modifier = modifier ^ kCGEventFlagMaskShift; } if (control) { modifier = modifier ^ kCGEventFlagMaskControl; } [self sendKeyCode:keyCode withModifier:modifier]; } -(void) sendKeyCode:(NSInteger)keyCode withModifier:(NSInteger)modifierMask { NSAssert(_source != NULL, @"You should call -beginKeyBoradEvents before sending a key event"); CGEventRef event; event = CGEventCreateKeyboardEvent(_source, keyCode, true); CGEventSetFlags(event, modifierMask); CGEventPost(_location, event); CFRelease(event); event = CGEventCreateKeyboardEvent(_source, keyCode, false); CGEventSetFlags(event, modifierMask); CGEventPost(_location, event); CFRelease(event); } -(void) endKeyBoradEvents { NSAssert(_source != NULL, @"You should call -beginKeyBoradEvents before end current keyborad event"); CFRelease(_source); _source = nil; } @end ================================================ FILE: VVDocumenter-Xcode/OCCategory/NSString+PDRegex/NSString+PDRegex.h ================================================ // // NSString+PDRegex.h // RegexOnNSString // // Created by Carl Brown on 10/3/11. // Copyright 2011 PDAgent, LLC. Released under MIT License. // #import @interface NSString (PDRegex) -(NSString *) vv_stringByReplacingRegexPattern:(NSString *)regex withString:(NSString *) replacement; -(NSString *) vv_stringByReplacingRegexPattern:(NSString *)regex withString:(NSString *) replacement caseInsensitive:(BOOL) ignoreCase; -(NSString *) vv_stringByReplacingRegexPattern:(NSString *)regex withString:(NSString *) replacement caseInsensitive:(BOOL) ignoreCase treatAsOneLine:(BOOL) assumeMultiLine; -(NSArray *) vv_stringsByExtractingGroupsUsingRegexPattern:(NSString *)regex; -(NSArray *) vv_stringsByExtractingGroupsUsingRegexPattern:(NSString *)regex caseInsensitive:(BOOL) ignoreCase treatAsOneLine:(BOOL) assumeMultiLine; -(BOOL) vv_matchesPatternRegexPattern:(NSString *)regex; -(BOOL) vv_matchesPatternRegexPattern:(NSString *)regex caseInsensitive:(BOOL) ignoreCase treatAsOneLine:(BOOL) assumeMultiLine; @end ================================================ FILE: VVDocumenter-Xcode/OCCategory/NSString+PDRegex/NSString+PDRegex.m ================================================ // // NSString+PDRegex.m // RegexOnNSString // // Created by Carl Brown on 10/3/11. // Copyright 2011 PDAgent, LLC. Released under MIT License. // #import "NSString+PDRegex.h" @implementation NSString (PDRegex) -(NSString *) vv_stringByReplacingRegexPattern:(NSString *)regex withString:(NSString *) replacement caseInsensitive:(BOOL)ignoreCase { return [self vv_stringByReplacingRegexPattern:regex withString:replacement caseInsensitive:ignoreCase treatAsOneLine:NO]; } -(NSString *) vv_stringByReplacingRegexPattern:(NSString *)regex withString:(NSString *) replacement caseInsensitive:(BOOL) ignoreCase treatAsOneLine:(BOOL) assumeMultiLine { NSUInteger options=0; if (ignoreCase) { options = options | NSRegularExpressionCaseInsensitive; } if (assumeMultiLine) { options = options | NSRegularExpressionDotMatchesLineSeparators; } NSError *error=nil; NSRegularExpression *pattern = [NSRegularExpression regularExpressionWithPattern:regex options:options error:&error]; if (error) { NSLog(@"Error creating Regex: %@",[error description]); return nil; } NSString *retVal= [pattern stringByReplacingMatchesInString:self options:0 range:NSMakeRange(0, [self length]) withTemplate:replacement]; return retVal; } -(NSString *) vv_stringByReplacingRegexPattern:(NSString *)regex withString:(NSString *) replacement { return [self vv_stringByReplacingRegexPattern:regex withString:replacement caseInsensitive:NO treatAsOneLine:NO]; } -(NSArray *) vv_stringsByExtractingGroupsUsingRegexPattern:(NSString *)regex caseInsensitive:(BOOL) ignoreCase treatAsOneLine:(BOOL) assumeMultiLine { NSUInteger options=0; if (ignoreCase) { options = options | NSRegularExpressionCaseInsensitive; } if (assumeMultiLine) { options = options | NSRegularExpressionDotMatchesLineSeparators; } NSError *error=nil; NSRegularExpression *pattern = [NSRegularExpression regularExpressionWithPattern:regex options:options error:&error]; if (error) { NSLog(@"Error creating Regex: %@",[error description]); return nil; } __block NSMutableArray *retVal = [NSMutableArray array]; [pattern enumerateMatchesInString:self options:0 range:NSMakeRange(0, [self length]) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { //Note, we only want to return the things in parens, so we're skipping index 0 intentionally for (int i=1; i<[result numberOfRanges]; i++) { NSString *matchedString=[self substringWithRange:[result rangeAtIndex:i]]; [retVal addObject:matchedString]; } }]; return retVal; } -(NSArray *) vv_stringsByExtractingGroupsUsingRegexPattern:(NSString *)regex { return [self vv_stringsByExtractingGroupsUsingRegexPattern:regex caseInsensitive:NO treatAsOneLine:NO]; } -(BOOL) vv_matchesPatternRegexPattern:(NSString *)regex caseInsensitive:(BOOL) ignoreCase treatAsOneLine:(BOOL) assumeMultiLine { NSUInteger options=0; if (ignoreCase) { options = options | NSRegularExpressionCaseInsensitive; } if (assumeMultiLine) { options = options | NSRegularExpressionDotMatchesLineSeparators; } NSError *error=nil; NSRegularExpression *pattern = [NSRegularExpression regularExpressionWithPattern:regex options:options error:&error]; if (error) { NSLog(@"Error creating Regex: %@",[error description]); return NO; //Can't possibly match an invalid Regex } return ([pattern numberOfMatchesInString:self options:0 range:NSMakeRange(0, [self length])] > 0); } -(BOOL) vv_matchesPatternRegexPattern:(NSString *)regex { return [self vv_matchesPatternRegexPattern:regex caseInsensitive:NO treatAsOneLine:NO]; } @end ================================================ FILE: VVDocumenter-Xcode/OCCategory/NSString+VVSyntax/NSString+VVSyntax.h ================================================ // // NSString+VVSyntax.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-18. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import @interface NSString (VVSyntax) -(NSString *) vv_stringByConvertingToUniform; -(NSString *) vv_stringByTrimEndSpaces; -(BOOL) vv_isObjCMethod; -(BOOL) vv_isProperty; -(BOOL) vv_isCFunction; -(BOOL) vv_isMacro; -(BOOL) vv_isEnum; -(BOOL) vv_isStruct; -(BOOL) vv_isUnion; -(BOOL) vv_isComplieKeyword; -(BOOL) vv_isSwiftFunction; -(BOOL) vv_isSwiftEnum; -(BOOL) vv_isSwiftProperty; -(BOOL) vv_isSwiftExtension; @end ================================================ FILE: VVDocumenter-Xcode/OCCategory/NSString+VVSyntax/NSString+VVSyntax.m ================================================ // // NSString+VVSyntax.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-18. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "NSString+VVSyntax.h" @implementation NSString (VVSyntax) -(NSString *) vv_stringByConvertingToUniform { return [[[self vv_stringByReplacingRegexPattern:@"\\s*\\(" withString:@"("] vv_stringByReplacingRegexPattern:@"\\)\\s*" withString:@")"] vv_stringByReplacingRegexPattern:@"\\s*\n\\s*" withString:@" "]; } -(NSString *) vv_stringByTrimEndSpaces { return [self vv_stringByReplacingRegexPattern:@"\\s*\n" withString:@"\n"]; } -(BOOL) vv_isObjCMethod { return [self vv_matchesPatternRegexPattern:@"^\\s*[+-]"]; } -(BOOL) vv_isCFunction { return ![self vv_isEnum] && ![self vv_isMacro] && ![self vv_isObjCMethod] && ![self vv_isProperty] && ![self vv_isComplieKeyword] && ![self vv_isSwiftFunction] && ![self vv_isSwiftEnum] && ![self vv_isSwiftProperty] && [self vv_matchesPatternRegexPattern:@".+\\s+.+\\("]; } -(BOOL) vv_isProperty { return [self vv_matchesPatternRegexPattern:@"^\\s*\\@property"]; } -(BOOL) vv_isMacro { return [self vv_matchesPatternRegexPattern:@"^\\s*\\#define"]; } -(BOOL) vv_isStruct { return [self vv_matchesPatternRegexPattern:@"^\\s*(\\w+\\s)?struct.*\\{"]; } -(BOOL) vv_isEnum { return [self vv_matchesPatternRegexPattern:@"^\\s*(\\w+\\s+)?NS_(ENUM|OPTIONS)\\b"]; } -(BOOL) vv_isUnion { return [self vv_matchesPatternRegexPattern:@"^\\s*(\\w+\\s)?union.*\\{"]; } -(BOOL) vv_isComplieKeyword { return ![self vv_isProperty] && [self vv_matchesPatternRegexPattern:@"^\\s*\\@"]; } -(BOOL) vv_isSwiftFunction { return ![self vv_isObjCMethod] && ![self vv_isSwiftProperty] && [self vv_matchesPatternRegexPattern:@"^\\s*(.*\\s+)?(func\\s+)|(init|deinit|subscript)"]; } -(BOOL) vv_isSwiftEnum { return ![self vv_isSwiftProperty] && [self vv_matchesPatternRegexPattern:@"^\\s*(.*\\s+)?enum\\s+"]; } -(BOOL) vv_isSwiftProperty { // Opt out the situation of `class func` if ([self vv_matchesPatternRegexPattern:@"class func"]) { return NO; } // `let`/`var` can be in swift func, but `(` appear before `let`/`var` only // happens when `private(set)` or `internal(set)` is used // typealias is considered to share the same comment as property. return [self vv_matchesPatternRegexPattern:@"^\\s*([^(]*?)(((\\s*let|var|typealias|class\\s*)\\s+)|(\\(\\s*set\\s*\\)))"]; } -(BOOL) vv_isSwiftExtension { return [self vv_matchesPatternRegexPattern:@"^\\s*(.*\\s+)?extension\\s+"]; } @end ================================================ FILE: VVDocumenter-Xcode/OCCategory/NSString+VVTextGetter/NSString+VVTextGetter.h ================================================ // // NSString+VVTextGetter.h // VVDocumenter-Xcode // // Created by 王 巍 on 14-7-31. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import @class VVTextResult; @interface NSString (VVTextGetter) -(VVTextResult *) vv_textResultOfCurrentLineCurrentLocation:(NSInteger)location; -(VVTextResult *) vv_textResultOfPreviousLineCurrentLocation:(NSInteger)location; -(VVTextResult *) vv_textResultOfNextLineCurrentLocation:(NSInteger)location; -(VVTextResult *) vv_textResultUntilNextString:(NSString *)findString currentLocation:(NSInteger)location; -(VVTextResult *) vv_textResultWithPairOpenString:(NSString *)open closeString:(NSString *)close currentLocation:(NSInteger)location; -(VVTextResult *) vv_textResultMatchPartWithPairOpenString:(NSString *)open closeString:(NSString *)close currentLocation:(NSInteger)location; -(VVTextResult *) vv_textResultToEndOfFileCurrentLocation:(NSInteger)location; @end ================================================ FILE: VVDocumenter-Xcode/OCCategory/NSString+VVTextGetter/NSString+VVTextGetter.m ================================================ // // NSString+VVTextGetter.m // VVDocumenter-Xcode // // Created by 王 巍 on 14-7-31. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "NSString+VVTextGetter.h" #import "VVTextResult.h" @implementation NSString (VVTextGetter) -(VVTextResult *) vv_textResultOfCurrentLineCurrentLocation:(NSInteger)location { NSInteger curseLocation = location; NSRange range = NSMakeRange(0, curseLocation); NSRange thisLineRange = [self rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:NSBackwardsSearch range:range]; NSString *line = nil; if (thisLineRange.location != NSNotFound) { NSRange lineRange = NSMakeRange(thisLineRange.location + 1, curseLocation - thisLineRange.location - 1); if (lineRange.location < [self length] && NSMaxRange(lineRange) < [self length]) { line = [self substringWithRange:lineRange]; return [[VVTextResult alloc] initWithRange:lineRange string:line]; } else { return nil; } } else { return nil; } } -(VVTextResult *) vv_textResultOfPreviousLineCurrentLocation:(NSInteger)location { NSInteger curseLocation = location; NSRange range = NSMakeRange(0, curseLocation); NSRange thisLineRange = [self rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:NSBackwardsSearch range:range]; NSString *line = nil; if (thisLineRange.location != NSNotFound) { range = NSMakeRange(0, thisLineRange.location); NSRange previousLineRange = [self rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:NSBackwardsSearch range:range]; if (previousLineRange.location != NSNotFound) { NSRange lineRange = NSMakeRange(previousLineRange.location + 1, thisLineRange.location - previousLineRange.location); if (lineRange.location < [self length] && NSMaxRange(lineRange) < [self length]) { line = [self substringWithRange:lineRange]; return [[VVTextResult alloc] initWithRange:lineRange string:line]; } else { return nil; } } else { return nil; } } else { return nil; } } -(VVTextResult *) vv_textResultOfNextLineCurrentLocation:(NSInteger)location { NSInteger curseLocation = location; NSRange range = NSMakeRange(curseLocation, self.length - curseLocation); NSRange thisLineRange = [self rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:0 range:range]; NSString *line = nil; if (thisLineRange.location != NSNotFound) { range = NSMakeRange(thisLineRange.location + 1, self.length - thisLineRange.location - 1); NSRange nextLineRange = [self rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:0 range:range]; if (nextLineRange.location != NSNotFound) { NSRange lineRange = NSMakeRange(thisLineRange.location + 1, NSMaxRange(nextLineRange) - NSMaxRange(thisLineRange)); if (lineRange.location < [self length] && NSMaxRange(lineRange) < [self length]) { line = [self substringWithRange:lineRange]; return [[VVTextResult alloc] initWithRange:lineRange string:line]; } else { return nil; } } else { return nil; } } else { return nil; } } -(VVTextResult *) vv_textResultUntilNextString:(NSString *)findString currentLocation:(NSInteger)location { NSInteger curseLocation = location; NSRange range = NSMakeRange(curseLocation, self.length - curseLocation); NSRange nextLineRange = [self rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:0 range:range]; NSRange rangeToString = [self rangeOfString:findString options:0 range:range]; NSString *line = nil; if (nextLineRange.location != NSNotFound && rangeToString.location != NSNotFound && nextLineRange.location <= rangeToString.location) { NSRange lineRange = NSMakeRange(nextLineRange.location + 1, rangeToString.location - nextLineRange.location); if (lineRange.location < [self length] && NSMaxRange(lineRange) <= [self length]) { line = [self substringWithRange:lineRange]; return [[VVTextResult alloc] initWithRange:lineRange string:line]; } else { return nil; } } else { return nil; } } -(VVTextResult *) vv_textResultMatchPartWithPairOpenString:(NSString *)open closeString:(NSString *)close currentLocation:(NSInteger)location { return [self textResultWithPairOpenString:open closeString:close currentLocation:location extractMatch:YES]; } -(VVTextResult *) vv_textResultWithPairOpenString:(NSString *)open closeString:(NSString *)close currentLocation:(NSInteger)location { return [self textResultWithPairOpenString:open closeString:close currentLocation:location extractMatch:NO]; } -(VVTextResult *) vv_textResultToEndOfFileCurrentLocation:(NSInteger)location { NSRange range = NSMakeRange(location, self.length - location); VVTextResult *result = [[VVTextResult alloc] initWithRange:range string:[self substringWithRange:range]]; return result; } -(VVTextResult *) textResultWithPairOpenString:(NSString *)open closeString:(NSString *)close currentLocation:(NSInteger)location extractMatch:(BOOL)extract { // Find all content from current positon to the last paired scope. Useful when pairing `{}` or `()` NSInteger curseLocation = location; NSRange range = NSMakeRange(curseLocation, self.length - curseLocation); // searchRange will be updated to new range later, for search the next open/close token. NSRange searchRange = range; VVLog(@"Begin Search Range: %lu, %lu", (unsigned long)searchRange.location, (unsigned long)searchRange.length); NSInteger openCount = 0; NSInteger closeCount = 0; NSRange nextOpenRange = [self rangeOfString:open options:0 range:searchRange]; NSRange nextCloseRange = [self rangeOfString:close options:0 range:searchRange]; NSRange firstOpenRange = nextOpenRange; // Not even open. Early return if (nextOpenRange.location == NSNotFound || nextCloseRange.location == NSNotFound || nextCloseRange.location < nextOpenRange.location) { return nil; } openCount++; // Update the search range: from current token to the end. searchRange = NSMakeRange(nextOpenRange.location + 1, self.length - nextOpenRange.location - 1); VVLog(@"Update Search Range: %lu, %lu", (unsigned long)searchRange.location, (unsigned long)searchRange.length); // Try to find the scope by pairing open and close count NSRange targetRange = NSMakeRange(0,0); while (openCount != closeCount) { // Get next open and close token location nextOpenRange = [self rangeOfString:open options:0 range:searchRange]; nextCloseRange = [self rangeOfString:close options:0 range:searchRange]; // No new close token. This scope will not close. if (nextCloseRange.location == NSNotFound) { return nil; } if (nextOpenRange.location < nextCloseRange.location) { targetRange = nextOpenRange; openCount++; } else { targetRange = nextCloseRange; closeCount++; } VVLog(@"Open:%ld, Close:%ld",(long)openCount,(long)closeCount); // Update the search range: from current token to the end. searchRange = NSMakeRange(targetRange.location + 1, self.length - targetRange.location - 1); VVLog(@"Target Range: %lu, %lu",targetRange.location,targetRange.length); VVLog(@"Update Search Range: %lu, %lu", (unsigned long)searchRange.location, (unsigned long)searchRange.length); } NSRange resultRange; if (extract) { resultRange = NSMakeRange(firstOpenRange.location, targetRange.location - firstOpenRange.location + 1); } else { // Extract the code need to be documented. From next line to the matched scope end. NSRange nextLineRange = [self rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:0 range:range]; resultRange = NSMakeRange(nextLineRange.location + 1, targetRange.location - nextLineRange.location); } if (resultRange.location < [self length] && NSMaxRange(resultRange) <= [self length]) { NSString *result = [self substringWithRange:resultRange]; return [[VVTextResult alloc] initWithRange:resultRange string:result]; } else { return nil; } } @end ================================================ FILE: VVDocumenter-Xcode/OCCategory/NSTextView+VVTextGetter/NSTextView+VVTextGetter.h ================================================ // // NSTextView+VVTextGetter.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import @class VVTextResult; @interface NSTextView (VVTextGetter) -(NSInteger) vv_currentCurseLocation; -(VVTextResult *) vv_textResultOfCurrentLine; -(VVTextResult *) vv_textResultOfPreviousLine; -(VVTextResult *) vv_textResultOfNextLine; -(VVTextResult *) vv_textResultUntilNextString:(NSString *)findString; -(VVTextResult *) vv_textResultWithPairOpenString:(NSString *)open closeString:(NSString *)close; -(VVTextResult *) vv_textResultToEndOfFile; @end ================================================ FILE: VVDocumenter-Xcode/OCCategory/NSTextView+VVTextGetter/NSTextView+VVTextGetter.m ================================================ // // NSTextView+VVTextGetter.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "NSTextView+VVTextGetter.h" #import "VVTextResult.h" #import "NSString+VVTextGetter.h" @implementation NSTextView (VVTextGetter) -(NSInteger) vv_currentCurseLocation { return [[[self selectedRanges] objectAtIndex:0] rangeValue].location; } -(VVTextResult *) vv_textResultOfCurrentLine { return [self.textStorage.string vv_textResultOfCurrentLineCurrentLocation:[self vv_currentCurseLocation]]; } -(VVTextResult *) vv_textResultOfPreviousLine { return [self.textStorage.string vv_textResultOfPreviousLineCurrentLocation:[self vv_currentCurseLocation]]; } -(VVTextResult *) vv_textResultOfNextLine { return [self.textStorage.string vv_textResultOfNextLineCurrentLocation:[self vv_currentCurseLocation]]; } -(VVTextResult *) vv_textResultUntilNextString:(NSString *)findString { return [self.textStorage.string vv_textResultUntilNextString:findString currentLocation:[self vv_currentCurseLocation]]; } -(VVTextResult *) vv_textResultWithPairOpenString:(NSString *)open closeString:(NSString *)close { return [self.textStorage.string vv_textResultWithPairOpenString:open closeString:close currentLocation:[self vv_currentCurseLocation]]; } -(VVTextResult *) vv_textResultToEndOfFile { return [self.textStorage.string vv_textResultToEndOfFileCurrentLocation:[self vv_currentCurseLocation]]; } @end ================================================ FILE: VVDocumenter-Xcode/OCCategory/VVTextResult.h ================================================ // // VVTextResult.h // VVDocumenter-Xcode // // Created by 王 巍 on 14-7-31. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import @interface VVTextResult : NSObject @property (nonatomic, assign) NSRange range; @property (nonatomic, copy) NSString *string; -(instancetype) initWithRange:(NSRange)aRange string:(NSString *)aString; @end ================================================ FILE: VVDocumenter-Xcode/OCCategory/VVTextResult.m ================================================ // // VVTextResult.m // VVDocumenter-Xcode // // Created by 王 巍 on 14-7-31. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVTextResult.h" @implementation VVTextResult -(instancetype) initWithRange:(NSRange)aRange string:(NSString *)aString { self = [super init]; if (self) { _range = aRange; _string = aString; } return self; } -(NSString *)description { return [NSString stringWithFormat:@"Location:%ld, Length:%ld, String:%@",self.range.location,self.range.length,self.string]; } @end ================================================ FILE: VVDocumenter-Xcode/ProjectHelper/VVProject.h ================================================ // // VVProject.h // VVDocumenter-Xcode // // Created by 夏天味道 on 15/6/25. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import @interface VVProject : NSObject @property (nonatomic, copy) NSString *directoryPath; @property (nonatomic,copy,readonly) NSString *workspacePath; @property (nonatomic, copy) NSString *projectName; @property (nonatomic, copy) NSDictionary *infoDictionary; @property (nonatomic, copy) NSString *projectVersion; @property (nonatomic,copy) NSDictionary *pbxprojDictionary; @property (nonatomic,copy) NSString *organizeationName; + (instancetype)projectForKeyWindow; @end ================================================ FILE: VVDocumenter-Xcode/ProjectHelper/VVProject.m ================================================ // // VVProject.m // VVDocumenter-Xcode // // Created by 夏天味道 on 15/6/25. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVProject.h" #import "VVWorkspaceManager.h" @implementation VVProject + (instancetype)projectForKeyWindow { id workspace = [VVWorkspaceManager workspaceForKeyWindow]; id contextManager = [workspace valueForKey:@"_runContextManager"]; for (id scheme in[contextManager valueForKey:@"runContexts"]) { NSString *schemeName = [scheme valueForKey:@"name"]; if (![schemeName hasPrefix:@"Pods-"]) { NSString *path = [VVWorkspaceManager directoryPathForWorkspace:workspace]; return [[VVProject alloc] initWithName:schemeName path:path]; } } return nil; } - (id)initWithName:(NSString *)name path:(NSString *)path { if (self = [self init]) { _projectName = name; _directoryPath = path; NSString *pbxprojPath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.xcodeproj/project.pbxproj",name]]; _pbxprojDictionary = [NSDictionary dictionaryWithContentsOfFile:pbxprojPath]; _organizeationName = [self getOrganizeationName]; NSString *infoplistName = [self infoplistNameWithAtScheme:name]; NSString *infoPath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", infoplistName]]; _infoDictionary = [NSDictionary dictionaryWithContentsOfFile:infoPath]; _projectVersion = self.infoDictionary[@"CFBundleShortVersionString"]; } return self; } -(NSString *)getOrganizeationName{ NSDictionary *objects = [_pbxprojDictionary objectForKey:@"objects"]; NSString *rootObjectId = [_pbxprojDictionary objectForKey:@"rootObject"]; NSDictionary *pbxProjectDic = [objects objectForKey:rootObjectId]; NSDictionary *attributes = [pbxProjectDic objectForKey:@"attributes"]; NSString *organizeationName = [attributes objectForKey:@"ORGANIZATIONNAME"]; return organizeationName; } -(NSString *)infoplistNameWithAtScheme:(NSString *)currentSchemeName{ NSDictionary *objects = [_pbxprojDictionary objectForKey:@"objects"]; NSString *rootObjectId = [_pbxprojDictionary objectForKey:@"rootObject"]; NSDictionary *pbxProjectDic = [objects objectForKey:rootObjectId]; NSArray *targetIds = [pbxProjectDic objectForKey:@"targets"]; NSString *currentTargetId; for (NSString *targetId in targetIds) { NSDictionary *targetDic = [objects objectForKey:targetId]; NSString *targetName = [targetDic objectForKey:@"name"]; if ([targetName isEqualToString:currentSchemeName]) { currentTargetId = targetId; break; } } if (!currentTargetId) { currentTargetId = [targetIds firstObject]; } NSDictionary *targetDic = [objects objectForKey:currentTargetId]; NSString *buildConfigurationListId = [targetDic objectForKey:@"buildConfigurationList"]; NSDictionary *buildConfigurationListDic = [objects objectForKey:buildConfigurationListId]; NSArray *buildConfigurationIds = [buildConfigurationListDic objectForKey:@"buildConfigurations"]; NSString *debugBuildConfigurationId; for (NSString *buildConfigurationId in buildConfigurationIds) { NSDictionary *buildConfigurationDic = [objects objectForKey:buildConfigurationId]; NSString *name = [buildConfigurationDic objectForKey:@"name"]; if ([name isEqualToString:@"Debug"]) { debugBuildConfigurationId = buildConfigurationId; break; } } if (!debugBuildConfigurationId) { debugBuildConfigurationId = [buildConfigurationIds firstObject]; } NSDictionary *buildConfigurationDic = [objects objectForKey:debugBuildConfigurationId]; NSDictionary *buildSettings = [buildConfigurationDic objectForKey:@"buildSettings"]; NSString *infoplistName = [buildSettings objectForKey:@"INFOPLIST_FILE"]; return infoplistName; } @end ================================================ FILE: VVDocumenter-Xcode/ProjectHelper/VVWorkspaceManager.h ================================================ // // VVWorkspaceManager.h // VVDocumenter-Xcode // // Created by 夏天味道 on 15/6/25. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import @interface VVWorkspaceManager : NSObject + (id)workspaceForKeyWindow; + (NSString *)currentWorkspaceDirectoryPath; + (NSString *)directoryPathForWorkspace:(id)workspace; @end ================================================ FILE: VVDocumenter-Xcode/ProjectHelper/VVWorkspaceManager.m ================================================ // // VVWorkspaceManager.m // VVDocumenter-Xcode // // Created by 夏天味道 on 15/6/25. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVWorkspaceManager.h" @implementation VVWorkspaceManager + (NSString *)currentWorkspaceDirectoryPath { return [self directoryPathForWorkspace:[self workspaceForKeyWindow]]; } + (NSString *)directoryPathForWorkspace:(id)workspace { NSString *workspacePath = [[workspace valueForKey:@"representingFilePath"] valueForKey:@"_pathString"]; return [workspacePath stringByDeletingLastPathComponent]; } #pragma mark - Private + (id)workspaceForKeyWindow { return [self workspaceForWindow:[NSApp keyWindow]]; } + (id)workspaceForWindow:(NSWindow *)window { NSArray *workspaceWindowControllers = [NSClassFromString(@"IDEWorkspaceWindowController") valueForKey:@"workspaceWindowControllers"]; for (id controller in workspaceWindowControllers) { if ([[controller valueForKey:@"window"] isEqual:window]) { return [controller valueForKey:@"_workspace"]; } } return nil; } @end ================================================ FILE: VVDocumenter-Xcode/Setting/VVDSettingPanelWindowController.h ================================================ // // VVDSettingPanelWindowController.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-8-3. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import @interface VVDSettingPanelWindowController : NSWindowController @end ================================================ FILE: VVDocumenter-Xcode/Setting/VVDSettingPanelWindowController.m ================================================ // // VVDSettingPanelWindowController.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-8-3. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVDSettingPanelWindowController.h" #import "VVDocumenterSetting.h" @interface VVDSettingPanelWindowController () @property (weak) IBOutlet NSTextField *tfTrigger; @property (weak) IBOutlet NSButton *btnUseSpaces; @property (weak) IBOutlet NSTextField *tfSpaceCount; @property (weak) IBOutlet NSTextField *tfSpaceLabel; @property (weak) IBOutlet NSStepper *stepperCount; @property (weak) IBOutlet NSMatrix *mtxSinceOptions; @property (weak) IBOutlet NSMatrix *mtxPrefixOptions; @property (weak) IBOutlet NSButtonCell *btnPrefixWithWhitespace; @property (weak) IBOutlet NSButtonCell *btnPrefixWithStar; @property (weak) IBOutlet NSButtonCell *btnPrefixWithSlashes; @property (weak) IBOutlet NSButton *btnAddSinceToComment; @property (weak) IBOutlet NSButton *btnBriefDescription; @property (weak) IBOutlet NSButton *btnUseHeaderDoc; @property (weak) IBOutlet NSButton *btnBlankLinesBetweenSections; @property (weak) IBOutlet NSButton *btnAlightArgumentComments; @property (weak) IBOutlet NSButton *btnUseAuthorInformation; @property (weak) IBOutlet NSButton *btnUseDateInformation; @property (weak) IBOutlet NSTextField *tfAuthoInformation; @property (weak) IBOutlet NSTextField *tfDateInformaitonFormat; @property (weak) IBOutlet NSTextField *tfSinceVersion; @end @implementation VVDSettingPanelWindowController - (instancetype)initWithWindow:(NSWindow *)window { self = [super initWithWindow:window]; if (self) { // Initialization code here. } return self; } - (void)windowDidLoad { [super windowDidLoad]; // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. [self.tfTrigger setStringValue:[[VVDocumenterSetting defaultSetting] triggerString]]; self.btnUseSpaces.state = (NSCellStateValue)[[VVDocumenterSetting defaultSetting] useSpaces]; self.btnAddSinceToComment.state = (NSCellStateValue)[[VVDocumenterSetting defaultSetting] addSinceToComments]; self.mtxSinceOptions.enabled = [[VVDocumenterSetting defaultSetting] addSinceToComments]; [self.mtxSinceOptions selectCellAtRow:(NSInteger)[[VVDocumenterSetting defaultSetting] sinceOption] column:0]; self.tfSinceVersion.enabled = [[VVDocumenterSetting defaultSetting] addSinceToComments]; self.tfSinceVersion.stringValue = [[VVDocumenterSetting defaultSetting] sinceVersion]; self.btnBriefDescription.state = (NSCellStateValue)[[VVDocumenterSetting defaultSetting] briefDescription]; self.btnUseHeaderDoc.state = (NSCellStateValue)[[VVDocumenterSetting defaultSetting] useHeaderDoc]; self.btnBlankLinesBetweenSections.state = (NSCellStateValue)[[VVDocumenterSetting defaultSetting] blankLinesBetweenSections]; self.btnAlightArgumentComments.state = (NSCellStateValue)[[VVDocumenterSetting defaultSetting] alignArgumentComments]; self.btnUseAuthorInformation.state = (NSCellStateValue)[[VVDocumenterSetting defaultSetting] useAuthorInformation]; self.tfAuthoInformation.stringValue = [[VVDocumenterSetting defaultSetting] authorInformation]; self.btnUseDateInformation.state = (NSCellStateValue)[[VVDocumenterSetting defaultSetting] useDateInformation]; self.tfDateInformaitonFormat.stringValue = [[VVDocumenterSetting defaultSetting] dateInformationFormat]; if ([[VVDocumenterSetting defaultSetting] prefixWithStar]) { [self.mtxPrefixOptions selectCell:self.btnPrefixWithStar]; } else if ([[VVDocumenterSetting defaultSetting] prefixWithSlashes]) { [self.mtxPrefixOptions selectCell:self.btnPrefixWithSlashes]; } else { [self.mtxPrefixOptions selectCell:self.btnPrefixWithWhitespace]; } // Disable the slashes prefix option for HeaderDoc comments if (self.btnUseHeaderDoc.state == NSOnState) { self.btnPrefixWithSlashes.enabled = NO; } [self updateUseSpace:self.btnUseSpaces.state]; [self syncSpaceCount]; self.tfTrigger.delegate = self; self.tfDateInformaitonFormat.delegate = self; self.tfAuthoInformation.delegate = self; self.tfSinceVersion.delegate = self; } - (IBAction)stepperPressed:(id)sender { [[VVDocumenterSetting defaultSetting] setSpaceCount:self.stepperCount.integerValue]; [self syncSpaceCount]; } - (IBAction)btnResetPressed:(id)sender { [[VVDocumenterSetting defaultSetting] setUseSpaces:YES]; [[VVDocumenterSetting defaultSetting] setTriggerString:VVDDefaultTriggerString]; [[VVDocumenterSetting defaultSetting] setSpaceCount:2]; [[VVDocumenterSetting defaultSetting] setPrefixWithStar:YES]; [[VVDocumenterSetting defaultSetting] setPrefixWithSlashes:NO]; [[VVDocumenterSetting defaultSetting] setAddSinceToComments:NO]; [[VVDocumenterSetting defaultSetting] setSinceVersion:@""]; [[VVDocumenterSetting defaultSetting] setBriefDescription:NO]; [[VVDocumenterSetting defaultSetting] setUseHeaderDoc:NO]; [[VVDocumenterSetting defaultSetting] setBlankLinesBetweenSections:YES]; [[VVDocumenterSetting defaultSetting] setAlignArgumentComments:YES]; [[VVDocumenterSetting defaultSetting] setUseAuthorInformation:NO]; [[VVDocumenterSetting defaultSetting] setAuthorInformation:VVDDefaultAuthorString]; [[VVDocumenterSetting defaultSetting] setUseDateInformation:NO]; [[VVDocumenterSetting defaultSetting] setDateInformationFormat:VVDDefaultDateInfomationFormat]; self.btnUseSpaces.state = NSOnState; [self updateUseSpace:self.btnUseSpaces.state]; self.btnPrefixWithWhitespace.state = NSOffState; self.btnPrefixWithStar.state = NSOnState; self.btnPrefixWithSlashes.state = NSOffState; self.btnAddSinceToComment.state = NSOffState; self.tfSinceVersion.enabled = NO; self.mtxSinceOptions.enabled = NO; self.btnBriefDescription.state = NSOffState; [self.tfTrigger setStringValue:VVDDefaultTriggerString]; self.btnUseHeaderDoc.state = NSOffState; self.btnBlankLinesBetweenSections.state = NSOnState; self.btnAlightArgumentComments.state = NSOnState; self.btnUseAuthorInformation.state = NSOffState; self.tfAuthoInformation.stringValue = VVDDefaultAuthorString; self.btnUseDateInformation.state = NSOffState; self.tfDateInformaitonFormat.stringValue = VVDDefaultDateInfomationFormat; self.btnPrefixWithSlashes.enabled = YES; [self syncSpaceCount]; } - (IBAction)mtxSinceOptionPressed:(id)sender { VVDSinceOption option = self.mtxSinceOptions.selectedRow; [[VVDocumenterSetting defaultSetting] setSinceOption:option]; } - (IBAction)btnUseSpacesPressed:(id)sender { [[VVDocumenterSetting defaultSetting] setUseSpaces:self.btnUseSpaces.state]; [self updateUseSpace:self.btnUseSpaces.state]; } - (IBAction)mtxPrefixSettingPressed:(id)sender { id selectedCell = self.mtxPrefixOptions.selectedCell; [[VVDocumenterSetting defaultSetting] setPrefixWithStar:[selectedCell isEqual:self.btnPrefixWithStar]]; [[VVDocumenterSetting defaultSetting] setPrefixWithSlashes:[selectedCell isEqual:self.btnPrefixWithSlashes]]; } - (IBAction)btnAddSinceToCommentsPressed:(id)sender { BOOL enableSince = self.btnAddSinceToComment.state; [[VVDocumenterSetting defaultSetting] setAddSinceToComments:enableSince]; self.tfSinceVersion.enabled = enableSince; self.mtxSinceOptions.enabled = enableSince; } - (IBAction)btnBriefDescriptionPressed:(id)sender { [[VVDocumenterSetting defaultSetting] setBriefDescription:self.btnBriefDescription.state]; } - (IBAction)btnUseAuthorInformationPressed:(id)sender { [[VVDocumenterSetting defaultSetting] setUseAuthorInformation:self.btnUseAuthorInformation.state]; } - (IBAction)btnUseDateInformationPressed:(id)sender { [[VVDocumenterSetting defaultSetting] setUseDateInformation:self.btnUseDateInformation.state]; } -(void) syncSpaceCount { NSInteger spaceCount = [[VVDocumenterSetting defaultSetting] spaceCount]; [self.tfSpaceCount setIntegerValue:spaceCount]; [self.stepperCount setIntegerValue:spaceCount]; } -(void) updateUseSpace:(BOOL)useSpace { [self.tfSpaceCount setEnabled:useSpace]; [self.stepperCount setEnabled:useSpace]; self.tfSpaceLabel.textColor = useSpace ? [NSColor blackColor] : [NSColor grayColor]; } - (void)controlTextDidChange:(NSNotification *)notification { if([notification object] == self.tfTrigger) { [[VVDocumenterSetting defaultSetting] setTriggerString:self.tfTrigger.stringValue]; } if([notification object] == self.tfAuthoInformation) { [[VVDocumenterSetting defaultSetting] setAuthorInformation:self.tfAuthoInformation.stringValue]; } if([notification object] == self.tfDateInformaitonFormat) { [[VVDocumenterSetting defaultSetting] setDateInformationFormat:self.tfDateInformaitonFormat.stringValue]; } if ([notification object] == self.tfSinceVersion) { [[VVDocumenterSetting defaultSetting] setSinceVersion:self.tfSinceVersion.stringValue]; } } - (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor { if (control == self.tfTrigger) { if (self.tfTrigger.stringValue.length == 0) { [self.tfTrigger setStringValue:VVDDefaultTriggerString]; } } return YES; } - (IBAction)useHeaderDoc:(id)sender { [[VVDocumenterSetting defaultSetting] setUseHeaderDoc:self.btnUseHeaderDoc.state]; if (self.btnUseHeaderDoc.state == NSOnState) { self.btnPrefixWithSlashes.enabled = NO; // If the slashes option was selected, change to the default stars if ([self.mtxPrefixOptions.selectedCell isEqual:self.btnPrefixWithSlashes]) { [self.mtxPrefixOptions selectCell:self.btnPrefixWithStar]; // Update the settings in addition to the display [self.mtxPrefixOptions sendAction]; } } else { self.btnPrefixWithSlashes.enabled = YES; } } - (IBAction)blankLinesBetweenSections:(id)sender { [[VVDocumenterSetting defaultSetting] setBlankLinesBetweenSections:self.btnBlankLinesBetweenSections.state]; } - (IBAction)alignArgumentComments:(id)sender { [[VVDocumenterSetting defaultSetting] setAlignArgumentComments:self.btnAlightArgumentComments.state]; } @end ================================================ FILE: VVDocumenter-Xcode/Setting/VVDSettingPanelWindowController.xib ================================================ ================================================ FILE: VVDocumenter-Xcode/Setting/VVDocumenterSetting.h ================================================ // // VVDocumenterSetting.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-8-3. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import typedef NS_ENUM(NSInteger, VVDSinceOption) { VVDSinceOptionPlaceholder, VVDSinceOptionProjectVersion, VVDSinceOptionSpecificVersion, }; extern NSString *const VVDDefaultTriggerString; extern NSString *const VVDDefaultAuthorString; extern NSString *const VVDDefaultDateInfomationFormat; @interface VVDocumenterSetting : NSObject + (VVDocumenterSetting *)defaultSetting; @property (readonly) NSInteger keyVCode; @property BOOL useSpaces; @property NSInteger spaceCount; @property NSString *triggerString; @property VVDSinceOption sinceOption; @property BOOL prefixWithStar; @property BOOL prefixWithSlashes; @property BOOL addSinceToComments; @property NSString *sinceVersion; @property BOOL briefDescription; @property BOOL useHeaderDoc; @property BOOL blankLinesBetweenSections; @property BOOL alignArgumentComments; @property BOOL useAuthorInformation; @property NSString *authorInformation; @property BOOL useDateInformation; @property NSString *dateInformationFormat; @property (readonly) NSString *spacesString; @end ================================================ FILE: VVDocumenter-Xcode/Setting/VVDocumenterSetting.m ================================================ // // VVDocumenterSetting.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-8-3. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVDocumenterSetting.h" #import #import "VVProject.h" NSString *const VVDDefaultTriggerString = @"///"; NSString *const VVDDefaultAuthorString = @""; NSString *const VVDDefaultDateInfomationFormat = @"YY-MM-dd HH:MM:ss"; NSString *const kVVDUseSpaces = @"com.onevcat.VVDocumenter.useSpaces"; NSString *const kVVDSpaceCount = @"com.onevcat.VVDocumenter.spaceCount"; NSString *const kVVDTriggerString = @"com.onevcat.VVDocumenter.triggerString"; NSString *const kVVDPrefixWithStar = @"com.onevcat.VVDocumenter.prefixWithStar"; NSString *const kVVDPrefixWithSlashes = @"com.onevcat.VVDocumenter.prefixWithSlashes"; NSString *const kVVDAddSinceToComments = @"com.onevcat.VVDocumenter.addSinceToComments"; NSString *const kVVDSinceVersion = @"com.onevcat.VVDocumenter.sinceVersion"; NSString *const kVVDSinceOption = @"com.onevcat.VVDocumenter.sinceOption"; NSString *const kVVDBriefDescription = @"com.onevcat.VVDocumenter.briefDescription"; NSString *const kVVDUserHeaderDoc = @"com.onevcat.VVDocumenter.useHeaderDoc"; NSString *const kVVDNoBlankLinesBetweenFields = @"com.onevcat.VVDocumenter.noBlankLinesBetweenFields"; NSString *const kVVDNoArgumentPadding = @"com.onevcat.VVDocumenter.noArgumentPadding"; NSString *const kVVDUseAuthorInformation = @"com.onevcat.VVDocumenter.useAuthorInformation"; NSString *const kVVDAuthorInfomation = @"com.onevcat.VVDocumenter.authorInfomation"; NSString *const kVVDUseDateInformation = @"com.onevcat.VVDocumenter.useDateInformation"; NSString *const kVVDDateInformationFormat = @"com.onevcat.VVDocumenter.dateInformationFomat"; @implementation VVDocumenterSetting + (VVDocumenterSetting *)defaultSetting { static dispatch_once_t once; static VVDocumenterSetting *defaultSetting; dispatch_once(&once, ^ { defaultSetting = [[VVDocumenterSetting alloc] init]; NSDictionary *defaults = @{kVVDPrefixWithStar: @YES, kVVDUseSpaces: @YES}; [[NSUserDefaults standardUserDefaults] registerDefaults:defaults]; }); return defaultSetting; } -(BOOL) useSpaces { return [[NSUserDefaults standardUserDefaults] boolForKey:kVVDUseSpaces]; } -(void) setUseSpaces:(BOOL)useSpace { [[NSUserDefaults standardUserDefaults] setBool:useSpace forKey:kVVDUseSpaces]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(NSInteger) keyVCode { TISInputSourceRef inputSource = TISCopyCurrentKeyboardLayoutInputSource(); NSString *layoutID = (__bridge NSString *)TISGetInputSourceProperty(inputSource, kTISPropertyInputSourceID); CFRelease(inputSource); // Possible dvorak layout SourceIDs: // com.apple.keylayout.Dvorak (System Qwerty) // But exclude: // com.apple.keylayout.DVORAK-QWERTYCMD (System Qwerty ⌘) // org.unknown.keylayout.DvorakImproved-Qwerty⌘ (http://www.macupdate.com/app/mac/24137/dvorak-improved-keyboard-layout) if ([layoutID localizedCaseInsensitiveContainsString:@"dvorak"] && ![layoutID localizedCaseInsensitiveContainsString: @"qwerty"]) { return kVK_ANSI_Period; } // Possible workman layout SourceIDs (https://github.com/ojbucao/Workman): // org.sil.ukelele.keyboardlayout.workman.workman // org.sil.ukelele.keyboardlayout.workman.workmanextended // org.sil.ukelele.keyboardlayout.workman.workman-io // org.sil.ukelele.keyboardlayout.workman.workman-p // org.sil.ukelele.keyboardlayout.workman.workman-pextended // org.sil.ukelele.keyboardlayout.workman.workman-dead if ([layoutID localizedCaseInsensitiveContainsString:@"workman"]) { return kVK_ANSI_B; } return kVK_ANSI_V; } -(NSInteger) spaceCount { NSInteger count = [[NSUserDefaults standardUserDefaults] integerForKey:kVVDSpaceCount]; return (count <= 0) ? 2 : count; } -(void) setSpaceCount:(NSInteger)spaceCount { if (spaceCount < 1) { spaceCount = 1; } else if (spaceCount > 10) { spaceCount = 10; } [[NSUserDefaults standardUserDefaults] setInteger:spaceCount forKey:kVVDSpaceCount]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(NSString *) triggerString { NSString *s = [[NSUserDefaults standardUserDefaults] stringForKey:kVVDTriggerString]; if (s.length == 0) { s = VVDDefaultTriggerString; } return s; } -(void) setTriggerString:(NSString *)triggerString { if (triggerString.length == 0) { [[NSUserDefaults standardUserDefaults] setObject:VVDDefaultTriggerString forKey:kVVDTriggerString]; } else { [[NSUserDefaults standardUserDefaults] setObject:triggerString forKey:kVVDTriggerString]; } [[NSUserDefaults standardUserDefaults] synchronize]; } -(VVDSinceOption) sinceOption { return (VVDSinceOption)[[NSUserDefaults standardUserDefaults] integerForKey:kVVDSinceOption]; } - (void)setSinceOption:(VVDSinceOption)sinceOption { [[NSUserDefaults standardUserDefaults] setInteger:sinceOption forKey:kVVDSinceOption]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(BOOL) prefixWithStar { return [[NSUserDefaults standardUserDefaults] boolForKey:kVVDPrefixWithStar]; } -(void) setPrefixWithStar:(BOOL)prefix { [[NSUserDefaults standardUserDefaults] setBool:prefix forKey:kVVDPrefixWithStar]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(BOOL) prefixWithSlashes { return [[NSUserDefaults standardUserDefaults] boolForKey:kVVDPrefixWithSlashes]; } -(void) setPrefixWithSlashes:(BOOL)prefix { [[NSUserDefaults standardUserDefaults] setBool:prefix forKey:kVVDPrefixWithSlashes]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(BOOL) addSinceToComments { return [[NSUserDefaults standardUserDefaults] boolForKey:kVVDAddSinceToComments]; } -(void) setAddSinceToComments:(BOOL)add { [[NSUserDefaults standardUserDefaults] setBool:add forKey:kVVDAddSinceToComments]; [[NSUserDefaults standardUserDefaults] synchronize]; } - (NSString *)sinceVersion { NSString *sinceVersion = [[NSUserDefaults standardUserDefaults] objectForKey:kVVDSinceVersion]; if ( ! sinceVersion ) { sinceVersion = @""; } return sinceVersion; } - (void)setSinceVersion:(NSString *)sinceVersion { [[NSUserDefaults standardUserDefaults] setObject:sinceVersion forKey:kVVDSinceVersion]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(BOOL) briefDescription { return [[NSUserDefaults standardUserDefaults] boolForKey:kVVDBriefDescription]; } -(void) setBriefDescription:(BOOL)brief { [[NSUserDefaults standardUserDefaults] setBool:brief forKey:kVVDBriefDescription]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(BOOL) useHeaderDoc { return [[NSUserDefaults standardUserDefaults] boolForKey:kVVDUserHeaderDoc]; } -(void) setUseHeaderDoc:(BOOL)use { [[NSUserDefaults standardUserDefaults] setBool:use forKey:kVVDUserHeaderDoc]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(BOOL) blankLinesBetweenSections { return ![[NSUserDefaults standardUserDefaults] boolForKey:kVVDNoBlankLinesBetweenFields]; } -(void) setBlankLinesBetweenSections:(BOOL)blankLinesBetweenFields { [[NSUserDefaults standardUserDefaults] setBool:!blankLinesBetweenFields forKey:kVVDNoBlankLinesBetweenFields]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(BOOL) alignArgumentComments { return ![[NSUserDefaults standardUserDefaults] boolForKey:kVVDNoArgumentPadding]; } -(void) setAlignArgumentComments:(BOOL)alignArgumentComments { [[NSUserDefaults standardUserDefaults] setBool:!alignArgumentComments forKey:kVVDNoArgumentPadding]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(BOOL)useAuthorInformation { return [[NSUserDefaults standardUserDefaults] boolForKey:kVVDUseAuthorInformation]; } -(void) setUseAuthorInformation:(BOOL)useAuthorInformation { [[NSUserDefaults standardUserDefaults] setBool:useAuthorInformation forKey:kVVDUseAuthorInformation]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(NSString *)authorInformation { NSString *authorInformation = [[NSUserDefaults standardUserDefaults] objectForKey:kVVDAuthorInfomation]; if (authorInformation.length <= 0 ) { NSString *name = [[VVProject projectForKeyWindow] organizeationName]; if (name.length <= 0) { NSDictionary *environment = [[NSProcessInfo processInfo] environment]; name = [environment objectForKey:@"LOGNAME"]; } if (name.length > 0) { authorInformation = name; }else{ authorInformation = VVDDefaultAuthorString; } } return authorInformation; } -(void)setAuthorInformation:(NSString *)authorInformation { [[NSUserDefaults standardUserDefaults] setObject:authorInformation forKey:kVVDAuthorInfomation]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(BOOL)useDateInformation { return [[NSUserDefaults standardUserDefaults] boolForKey:kVVDUseDateInformation]; } -(void) setUseDateInformation:(BOOL)useDateInformation { [[NSUserDefaults standardUserDefaults] setBool:useDateInformation forKey:kVVDUseDateInformation]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(NSString *)dateInformationFormat { NSString *formatString = [[NSUserDefaults standardUserDefaults] objectForKey:kVVDDateInformationFormat]; if (formatString == nil || formatString.length <= 0) { formatString = VVDDefaultDateInfomationFormat; } return formatString; } -(void)setDateInformationFormat:(NSString *)dateInformationFormat { [[NSUserDefaults standardUserDefaults] setObject:dateInformationFormat forKey:kVVDDateInformationFormat]; [[NSUserDefaults standardUserDefaults] synchronize]; } -(NSString *) spacesString { if ([self useSpaces]) { return [@"" stringByPaddingToLength:[self spaceCount] withString:@" " startingAtIndex:0]; } else { return @"\t"; } } @end ================================================ FILE: VVDocumenter-Xcode/VVDocumenter-Xcode-Info.plist ================================================ CFBundleDevelopmentRegion English CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 DVTPlugInCompatibilityUUIDs 9AFF134A-08DC-4096-8CEE-62A4BB123046 63FC1C47-140D-42B0-BB4D-A10B2D225574 37B30044-3B14-46BA-ABAA-F01000C27B63 640F884E-CE55-4B40-87C0-8869546CAB7A A2E4D43F-41F4-4FB9-BB94-7177011C9AED AD68E85B-441B-4301-B564-A45E4919A6AD C4A681B0-4A26-480E-93EC-1218098B9AA0 FEC992CC-CA4A-4CFD-8881-77300FCB848A 992275C1-432A-4CF7-B659-D84ED6D42D3F A16FF353-8441-459E-A50C-B071F53F51B7 9F75337B-21B4-4ADC-B558-F9CADF7073A7 992275C1-432A-4CF7-B659-D84ED6D42D3F 8DC44374-2B35-4C57-A6FE-2AD66A36AAD9 E969541F-E6F9-4D25-8158-72DC3545A6C6 AABB7188-E14E-4433-AD3B-5CD791EAD9A3 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 0420B86A-AA43-4792-9ED0-6FE0F2B16A13 CC0D0F4F-05B3-431A-8F33-F84AFCB2C651 7265231C-39B4-402C-89E1-16167C4CC990 F41BD31E-2683-44B8-AE7F-5F09E919790E E71C2CFE-BFD8-4044-8F06-00AE685A406C ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C E0A62D1F-3C18-4D74-BFE5-A4167D643966 NSHumanReadableCopyright Copyright © 2013年 OneV's Den. All rights reserved. NSPrincipalClass XC4Compatible XC5Compatible XCGCReady XCPluginHasUI ================================================ FILE: VVDocumenter-Xcode/VVDocumenter-Xcode-Prefix.pch ================================================ // // Prefix header for all source files of the 'VVDocumenter-Xcode' target in the 'VVDocumenter-Xcode' project // #ifdef __OBJC__ #import #import "NSString+PDRegex.h" #endif //#define __DEBUG__ 1 #ifdef __DEBUG__ #define VVLog(...) NSLog(__VA_ARGS__) #else #define VVLog(...) do{} while(0) #endif ================================================ FILE: VVDocumenter-Xcode/VVDocumenter.h ================================================ // // VVDocumenter.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import @interface VVDocumenter : NSObject -(instancetype) initWithCode:(NSString *)code; -(NSString *) baseIndentation; -(NSString *) document; @end ================================================ FILE: VVDocumenter-Xcode/VVDocumenter.m ================================================ // // VVDocumenter.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-17. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVDocumenter.h" #import "NSString+VVSyntax.h" #import "VVCommenter.h" @interface VVDocumenter() @property (nonatomic, copy) NSString *code; @property (nonatomic, assign) BOOL isEnum; @property (nonatomic, assign) BOOL isSwiftEnum; @end @implementation VVDocumenter -(instancetype) initWithCode:(NSString *)code { self = [super init]; if (self) { NSString *trimmed = [[code vv_stringByReplacingRegexPattern:@"\\s*(\\(.*\?\\))\\s*" withString:@"$1"] vv_stringByReplacingRegexPattern:@"\\s*\n\\s*" withString:@" "]; _isEnum = [trimmed vv_isEnum]; _isSwiftEnum = [trimmed vv_isSwiftEnum]; if (_isEnum || _isSwiftEnum) { _code = code; } else { //Trim the space around the braces //Then trim the new line character _code = trimmed; } } return self; } -(NSString *) baseIndentation { NSArray *matchedSpaces = [self.code vv_stringsByExtractingGroupsUsingRegexPattern:@"^(\\s*)"]; if (matchedSpaces.count > 0) { return matchedSpaces[0]; } else { return @""; } } -(NSString *) document { NSString *trimCode = [self.code stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; NSString *baseIndent = [self baseIndentation]; VVBaseCommenter *commenter = nil; if (self.isEnum) { commenter = [[VVEnumCommenter alloc] initWithIndentString:baseIndent codeString:trimCode]; } else if (self.isSwiftEnum) { commenter = [[VVSwiftEnumCommenter alloc] initWithIndentString:baseIndent codeString:trimCode]; } else if ([trimCode vv_isProperty]) { commenter = [[VVPropertyCommenter alloc] initWithIndentString:baseIndent codeString:trimCode]; } else if ([trimCode vv_isCFunction]) { commenter = [[VVFunctionCommenter alloc] initWithIndentString:baseIndent codeString:trimCode]; } else if ([trimCode vv_isMacro]) { commenter = [[VVMacroCommenter alloc] initWithIndentString:baseIndent codeString:trimCode]; } else if ([trimCode vv_isStruct]) { commenter = [[VVStructCommenter alloc] initWithIndentString:baseIndent codeString:trimCode]; } else if ([trimCode vv_isUnion]) { commenter = [[VVStructCommenter alloc] initWithIndentString:baseIndent codeString:trimCode]; } else if ([trimCode vv_isObjCMethod]) { commenter = [[VVMethodCommenter alloc] initWithIndentString:baseIndent codeString:trimCode]; } else if ([trimCode vv_isSwiftFunction]) { commenter = [[VVSwiftFunctionCommenter alloc] initWithIndentString:baseIndent codeString:trimCode]; } else if ([trimCode vv_isSwiftProperty]) { commenter = [[VVSwiftPropertyCommenter alloc] initWithIndentString:baseIndent codeString:trimCode]; } else if ([trimCode vv_isSwiftExtension]) { commenter = [[VVSwiftExtensionCommenter alloc] initWithIndentString:baseIndent codeString:trimCode]; } else { commenter = [[VVVariableCommenter alloc] initWithIndentString:baseIndent codeString:trimCode]; } if ([commenter shouldComment]) { return [commenter document]; } else { return nil; } } @end ================================================ FILE: VVDocumenter-Xcode/VVDocumenterManager.h ================================================ // // VVDocumenterManager.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-16. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import @interface VVDocumenterManager : NSObject @end ================================================ FILE: VVDocumenter-Xcode/VVDocumenterManager.m ================================================ // // VVDocumenterManager.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-16. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVDocumenterManager.h" #import "NSTextView+VVTextGetter.h" #import "NSString+VVSyntax.h" #import "VVDocumenter.h" #import "VVKeyboardEventSender.h" #import "VVDSettingPanelWindowController.h" #import "VVDocumenterSetting.h" #import "VVTextResult.h" @interface VVDocumenterManager() @property (nonatomic, strong) id eventMonitor; @property (nonatomic, assign) BOOL prefixTyped; @property (nonatomic, strong) VVDSettingPanelWindowController *settingPanel; @end @implementation VVDocumenterManager +(void)pluginDidLoad:(NSBundle *)plugin { VVLog(@"VVDocumenter: Plugin loaded successfully"); [self shared]; } +(instancetype) shared { static dispatch_once_t once; static id instance = nil; dispatch_once(&once, ^{ instance = [[self alloc] init]; }); return instance; } - (instancetype)init { if (self = [super init]) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidFinishLaunching:) name:NSApplicationDidFinishLaunchingNotification object:nil]; } return self; } - (void) applicationDidFinishLaunching: (NSNotification*) noti { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textStorageDidChange:) name:NSTextDidChangeNotification object:nil]; [self addSettingMenu]; } -(void) addSettingMenu { NSMenuItem *editMenuItem = [[NSApp mainMenu] itemWithTitle:@"Window"]; if (editMenuItem) { [[editMenuItem submenu] addItem:[NSMenuItem separatorItem]]; NSMenuItem *newMenuItem = [[NSMenuItem alloc] initWithTitle:@"VVDocumenter" action:@selector(showSettingPanel:) keyEquivalent:@""]; [newMenuItem setTarget:self]; [[editMenuItem submenu] addItem:newMenuItem]; } } -(void) showSettingPanel:(NSNotification *)noti { self.settingPanel = [[VVDSettingPanelWindowController alloc] initWithWindowNibName:@"VVDSettingPanelWindowController"]; [self.settingPanel showWindow:self.settingPanel]; } - (void) textStorageDidChange:(NSNotification *)noti { if ([[noti object] isKindOfClass:[NSTextView class]]) { NSTextView *textView = (NSTextView *)[noti object]; VVTextResult *currentLineResult = [textView vv_textResultOfCurrentLine]; if (currentLineResult) { //Check if there is a "//" already typed in. We do this to solve the undo issue //Otherwise when you press Cmd+Z, "///" will be recognized and trigger the doc inserting, so you can not perform an undo. NSString *triggerString = [[VVDocumenterSetting defaultSetting] triggerString]; if (triggerString.length > 1) { NSString *preTypeString = [triggerString substringToIndex:triggerString.length - 2]; self.prefixTyped = [currentLineResult.string vv_matchesPatternRegexPattern:[NSString stringWithFormat:@"^\\s*%@$",[NSRegularExpression escapedPatternForString:preTypeString]]] | self.prefixTyped; } else { self.prefixTyped = YES; } if ([currentLineResult.string vv_matchesPatternRegexPattern:[NSString stringWithFormat:@"^\\s*%@$",[NSRegularExpression escapedPatternForString:triggerString]]] && self.prefixTyped) { VVTextResult *previousLineResult = [textView vv_textResultOfPreviousLine]; // Previous line is a documentation comment, so ignore this if ([previousLineResult.string vv_matchesPatternRegexPattern:@"^\\s*///"]) { return; } VVTextResult *nextLineResult = [textView vv_textResultOfNextLine]; // Next line is a documentation comment, so ignore this if ([nextLineResult.string vv_matchesPatternRegexPattern:@"^\\s*///"]) { return; } //Get a @"///" (triggerString) typed in by user. Do work! self.prefixTyped = NO; __block BOOL shouldReplace = NO; //Decide which is closer to the cursor. A semicolon or a half brace. //We just want to document the next valid line. VVTextResult *resultUntilSemiColon = [textView vv_textResultUntilNextString:@";"]; VVTextResult *resultUntilBrace = [textView vv_textResultUntilNextString:@"{"]; VVTextResult *resultUntilFileEnd = [textView vv_textResultToEndOfFile]; VVTextResult *resultToDocument = nil; if (resultUntilSemiColon && resultUntilBrace) { resultToDocument = (resultUntilSemiColon.range.length < resultUntilBrace.range.length) ? resultUntilSemiColon : resultUntilBrace; } else if (resultUntilBrace) { resultToDocument = resultUntilBrace; } else if (resultUntilSemiColon) { resultToDocument = resultUntilSemiColon; } else { resultToDocument = resultUntilFileEnd; } //We always write document until semicolon for enum. (Maybe struct later) if ([resultToDocument.string vv_isEnum]) { resultToDocument = resultUntilSemiColon; shouldReplace = YES; } NSString *inputCode = nil; if ([resultToDocument.string vv_isSwiftEnum]) { inputCode = [textView vv_textResultWithPairOpenString:@"{" closeString:@"}"].string; } else { inputCode = [resultToDocument.string vv_stringByConvertingToUniform]; } VVDocumenter *doc = [[VVDocumenter alloc] initWithCode:inputCode]; NSString *documentationString = [doc document]; if (!documentationString) { //Leave the user's input there. //It might be no need to parse doc or something wrong. return; } //Now we are using a simulation of keyboard event to insert the docs, instead of using the IDE's private method. //See more at https://github.com/onevcat/VVDocumenter-Xcode/issues/3 //Save current content in paste board NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; NSString *originPBString = [pasteBoard stringForType:NSPasteboardTypeString]; //Set the doc comments in it [pasteBoard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; [pasteBoard setString:documentationString forType:NSStringPboardType]; //Begin to simulate keyborad pressing VVKeyboardEventSender *kes = [[VVKeyboardEventSender alloc] init]; [kes beginKeyBoradEvents]; //Cmd+delete Delete current line [kes sendKeyCode:kVK_Delete withModifierCommand:YES alt:NO shift:NO control:NO]; //if (shouldReplace) [textView setSelectedRange:resultToDocument.range]; //Cmd+V, paste (which key to actually use is based on the current keyboard layout) NSInteger kKeyVCode = [[VVDocumenterSetting defaultSetting] keyVCode]; [kes sendKeyCode:kKeyVCode withModifierCommand:YES alt:NO shift:NO control:NO]; //The key down is just a defined finish signal by me. When we receive this key, we know operation above is finished. [kes sendKeyCode:kVK_F20]; self.eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:^NSEvent *(NSEvent *incomingEvent) { if ([incomingEvent type] == NSKeyDown && [incomingEvent keyCode] == kVK_F20) { //Finish signal arrived, no need to observe the event [NSEvent removeMonitor:self.eventMonitor]; self.eventMonitor = nil; //Restore previois patse board content [pasteBoard setString:originPBString forType:NSStringPboardType]; //Set cursor before the inserted documentation. So we can use tab to begin edit. int baseIndentationLength = (int)[doc baseIndentation].length; [textView setSelectedRange:NSMakeRange(currentLineResult.range.location + baseIndentationLength, 0)]; //Send a 'tab' after insert the doc. For our lazy programmers. :) [kes sendKeyCode:kVK_Tab]; [kes endKeyBoradEvents]; shouldReplace = NO; //Invalidate the finish signal, in case you set it to do some other thing. return nil; } else if ([incomingEvent type] == NSKeyDown && [incomingEvent keyCode] == kKeyVCode && shouldReplace == YES) { //Select input line and the define code block. NSRange r = [textView vv_textResultUntilNextString:@";"].range; //NSRange r begins from the starting of enum(struct) line. Select 1 character before to include the trigger input line. [textView setSelectedRange:NSMakeRange(r.location - 1, r.length + 1)]; return incomingEvent; } else { return incomingEvent; } }]; } } } } @end ================================================ FILE: VVDocumenter-Xcode/en.lproj/InfoPlist.strings ================================================ /* Localized versions of Info.plist keys */ ================================================ FILE: VVDocumenter-Xcode.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 4B06DF741B315E9D007D69BE /* VVSwiftExtensionCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B50A26F1B315CF3008A4400 /* VVSwiftExtensionCommenter.m */; }; 4B50A2701B315CF3008A4400 /* VVSwiftExtensionCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B50A26F1B315CF3008A4400 /* VVSwiftExtensionCommenter.m */; }; 53C67935184501030030C553 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 893D8F7F18262EF500E8A00C /* Carbon.framework */; }; 893D8F8018262EF500E8A00C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 893D8F7F18262EF500E8A00C /* Carbon.framework */; }; C4052CFA1B3BB10700ED0CF0 /* VVProject.m in Sources */ = {isa = PBXBuildFile; fileRef = C4052CF71B3BB10700ED0CF0 /* VVProject.m */; }; C4052CFB1B3BB10700ED0CF0 /* VVWorkspaceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C4052CF91B3BB10700ED0CF0 /* VVWorkspaceManager.m */; }; C4052CFC1B3BB2C200ED0CF0 /* VVProject.m in Sources */ = {isa = PBXBuildFile; fileRef = C4052CF71B3BB10700ED0CF0 /* VVProject.m */; }; C4052CFD1B3BB2C200ED0CF0 /* VVWorkspaceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C4052CF91B3BB10700ED0CF0 /* VVWorkspaceManager.m */; }; D114BEE0179644D00043FA65 /* NSString+PDRegex.m in Sources */ = {isa = PBXBuildFile; fileRef = D114BEDE179644D00043FA65 /* NSString+PDRegex.m */; }; D114BEE3179644FA0043FA65 /* NSTextView+VVTextGetter.m in Sources */ = {isa = PBXBuildFile; fileRef = D114BEE2179644FA0043FA65 /* NSTextView+VVTextGetter.m */; }; D11C542D17999D9000D3DE38 /* VVArgument.m in Sources */ = {isa = PBXBuildFile; fileRef = D11C542B17999D9000D3DE38 /* VVArgument.m */; }; D124614717AC16820095F9D6 /* VVDocumenterSetting.m in Sources */ = {isa = PBXBuildFile; fileRef = D124614317AC16820095F9D6 /* VVDocumenterSetting.m */; }; D124614817AC16820095F9D6 /* VVDSettingPanelWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = D124614517AC16820095F9D6 /* VVDSettingPanelWindowController.m */; }; D124614917AC16820095F9D6 /* VVDSettingPanelWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D124614617AC16820095F9D6 /* VVDSettingPanelWindowController.xib */; }; D13EDDD91987F34C0029A555 /* VVSwiftFunctionCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D13EDDD81987F34C0029A555 /* VVSwiftFunctionCommenter.m */; }; D14070C418CE8819009B0EED /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D14070C318CE8819009B0EED /* XCTest.framework */; }; D14110A61988C07E00A7083F /* VVTestHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = D1C462EC17999C9A00EB7B23 /* VVTestHelper.m */; }; D14110A71988C08700A7083F /* VVDocumenterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D1C462E517999C2000EB7B23 /* VVDocumenterTests.m */; }; D14110A81988C12000A7083F /* VVArgument.m in Sources */ = {isa = PBXBuildFile; fileRef = D11C542B17999D9000D3DE38 /* VVArgument.m */; }; D14110A91988C12000A7083F /* VVBaseCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCD31796E088006719AA /* VVBaseCommenter.m */; }; D14110AA1988C12000A7083F /* VVPropertyCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCD61796E09E006719AA /* VVPropertyCommenter.m */; }; D14110AB1988C12000A7083F /* VVMethodCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCD91796E0AC006719AA /* VVMethodCommenter.m */; }; D14110AC1988C12000A7083F /* VVFunctionCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCDC1796E0B9006719AA /* VVFunctionCommenter.m */; }; D14110AD1988C12000A7083F /* VVSwiftFunctionCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D13EDDD81987F34C0029A555 /* VVSwiftFunctionCommenter.m */; }; D14110AE1988C12000A7083F /* VVMacroCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCDF1796E0C0006719AA /* VVMacroCommenter.m */; }; D14110AF1988C12000A7083F /* VVStructCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCE21796E0C9006719AA /* VVStructCommenter.m */; }; D14110B01988C12000A7083F /* VVEnumCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCE51796E0D0006719AA /* VVEnumCommenter.m */; }; D14110B11988C12000A7083F /* VVVariableCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCE81796E0D6006719AA /* VVVariableCommenter.m */; }; D14110B21988C12F00A7083F /* VVKeyboardEventSender.m in Sources */ = {isa = PBXBuildFile; fileRef = D1D66CA717A2AEF000E62F99 /* VVKeyboardEventSender.m */; }; D14110B31988C12F00A7083F /* NSString+VVSyntax.m in Sources */ = {isa = PBXBuildFile; fileRef = D1C462F417999CEC00EB7B23 /* NSString+VVSyntax.m */; }; D14110B41988C12F00A7083F /* NSString+PDRegex.m in Sources */ = {isa = PBXBuildFile; fileRef = D114BEDE179644D00043FA65 /* NSString+PDRegex.m */; }; D14110B51988C12F00A7083F /* NSTextView+VVTextGetter.m in Sources */ = {isa = PBXBuildFile; fileRef = D114BEE2179644FA0043FA65 /* NSTextView+VVTextGetter.m */; }; D14110B61988C12F00A7083F /* VVDocumenterManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D16917DE17955C8D0036C06B /* VVDocumenterManager.m */; }; D14110B71988C12F00A7083F /* VVDocumenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D1AC3B8E1796DB070063A484 /* VVDocumenter.m */; }; D14110B81988C14500A7083F /* VVDocumenterSetting.m in Sources */ = {isa = PBXBuildFile; fileRef = D124614317AC16820095F9D6 /* VVDocumenterSetting.m */; }; D14110B91988C14500A7083F /* VVDSettingPanelWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = D124614517AC16820095F9D6 /* VVDSettingPanelWindowController.m */; }; D14380F7179551B900C829CE /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D14380F6179551B900C829CE /* Cocoa.framework */; }; D1438101179551B900C829CE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D14380FF179551B900C829CE /* InfoPlist.strings */; }; D16AFCD41796E088006719AA /* VVBaseCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCD31796E088006719AA /* VVBaseCommenter.m */; }; D16AFCD71796E09E006719AA /* VVPropertyCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCD61796E09E006719AA /* VVPropertyCommenter.m */; }; D16AFCDA1796E0AC006719AA /* VVMethodCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCD91796E0AC006719AA /* VVMethodCommenter.m */; }; D16AFCDD1796E0B9006719AA /* VVFunctionCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCDC1796E0B9006719AA /* VVFunctionCommenter.m */; }; D16AFCE01796E0C0006719AA /* VVMacroCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCDF1796E0C0006719AA /* VVMacroCommenter.m */; }; D16AFCE31796E0C9006719AA /* VVStructCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCE21796E0C9006719AA /* VVStructCommenter.m */; }; D16AFCE61796E0D0006719AA /* VVEnumCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCE51796E0D0006719AA /* VVEnumCommenter.m */; }; D16AFCE91796E0D6006719AA /* VVVariableCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D16AFCE81796E0D6006719AA /* VVVariableCommenter.m */; }; D1737637198A4C8A00FE2355 /* NSString+VVTextGetter.m in Sources */ = {isa = PBXBuildFile; fileRef = D1737636198A4C8A00FE2355 /* NSString+VVTextGetter.m */; }; D173763A198A4CF700FE2355 /* VVTextResult.m in Sources */ = {isa = PBXBuildFile; fileRef = D1737639198A4CF700FE2355 /* VVTextResult.m */; }; D173763B198A53C000FE2355 /* NSString+VVTextGetter.m in Sources */ = {isa = PBXBuildFile; fileRef = D1737636198A4C8A00FE2355 /* NSString+VVTextGetter.m */; }; D173763C198A53C000FE2355 /* VVTextResult.m in Sources */ = {isa = PBXBuildFile; fileRef = D1737639198A4CF700FE2355 /* VVTextResult.m */; }; D18224DC17956290001A5E8A /* VVDocumenterManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D16917DE17955C8D0036C06B /* VVDocumenterManager.m */; }; D1986F74179A12BD00EA6643 /* CommenterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D1986F73179A12BD00EA6643 /* CommenterTests.m */; }; D1A6B1D0198A0D8600BCED83 /* VVSwiftPropertyCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D1A6B1CF198A0D8600BCED83 /* VVSwiftPropertyCommenter.m */; }; D1A6B1D1198A0D8600BCED83 /* VVSwiftPropertyCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D1A6B1CF198A0D8600BCED83 /* VVSwiftPropertyCommenter.m */; }; D1AC3B8F1796DB070063A484 /* VVDocumenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D1AC3B8E1796DB070063A484 /* VVDocumenter.m */; }; D1B316D6189A2AA700420A6E /* VVMethodTestsCode.plist in Resources */ = {isa = PBXBuildFile; fileRef = D1B316D5189A2AA700420A6E /* VVMethodTestsCode.plist */; }; D1C462DD17999C2000EB7B23 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D14380F6179551B900C829CE /* Cocoa.framework */; }; D1C462E317999C2000EB7B23 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D1C462E117999C2000EB7B23 /* InfoPlist.strings */; }; D1C462F117999CA200EB7B23 /* SyntaxTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D1C462F017999CA200EB7B23 /* SyntaxTests.m */; }; D1C462F517999CEC00EB7B23 /* NSString+VVSyntax.m in Sources */ = {isa = PBXBuildFile; fileRef = D1C462F417999CEC00EB7B23 /* NSString+VVSyntax.m */; }; D1C6124819891B3700FDB554 /* VVSwiftEnumCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D1C6124719891B3700FDB554 /* VVSwiftEnumCommenter.m */; }; D1C6124919891B3700FDB554 /* VVSwiftEnumCommenter.m in Sources */ = {isa = PBXBuildFile; fileRef = D1C6124719891B3700FDB554 /* VVSwiftEnumCommenter.m */; }; D1D66CA817A2AEF000E62F99 /* VVKeyboardEventSender.m in Sources */ = {isa = PBXBuildFile; fileRef = D1D66CA717A2AEF000E62F99 /* VVKeyboardEventSender.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 4B50A26E1B315CF3008A4400 /* VVSwiftExtensionCommenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVSwiftExtensionCommenter.h; sourceTree = ""; }; 4B50A26F1B315CF3008A4400 /* VVSwiftExtensionCommenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVSwiftExtensionCommenter.m; sourceTree = ""; }; 893D8F7F18262EF500E8A00C /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; C4052CF61B3BB10700ED0CF0 /* VVProject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVProject.h; sourceTree = ""; }; C4052CF71B3BB10700ED0CF0 /* VVProject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVProject.m; sourceTree = ""; }; C4052CF81B3BB10700ED0CF0 /* VVWorkspaceManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVWorkspaceManager.h; sourceTree = ""; }; C4052CF91B3BB10700ED0CF0 /* VVWorkspaceManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVWorkspaceManager.m; sourceTree = ""; }; D114BEDD179644D00043FA65 /* NSString+PDRegex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+PDRegex.h"; sourceTree = ""; }; D114BEDE179644D00043FA65 /* NSString+PDRegex.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+PDRegex.m"; sourceTree = ""; }; D114BEE1179644FA0043FA65 /* NSTextView+VVTextGetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTextView+VVTextGetter.h"; sourceTree = ""; }; D114BEE2179644FA0043FA65 /* NSTextView+VVTextGetter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSTextView+VVTextGetter.m"; sourceTree = ""; }; D11C542A17999D9000D3DE38 /* VVArgument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVArgument.h; sourceTree = ""; }; D11C542B17999D9000D3DE38 /* VVArgument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVArgument.m; sourceTree = ""; }; D11C542C17999D9000D3DE38 /* VVCommenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVCommenter.h; sourceTree = ""; }; D124614217AC16820095F9D6 /* VVDocumenterSetting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VVDocumenterSetting.h; path = "VVDocumenter-Xcode/Setting/VVDocumenterSetting.h"; sourceTree = SOURCE_ROOT; }; D124614317AC16820095F9D6 /* VVDocumenterSetting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VVDocumenterSetting.m; path = "VVDocumenter-Xcode/Setting/VVDocumenterSetting.m"; sourceTree = SOURCE_ROOT; }; D124614417AC16820095F9D6 /* VVDSettingPanelWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VVDSettingPanelWindowController.h; path = "VVDocumenter-Xcode/Setting/VVDSettingPanelWindowController.h"; sourceTree = SOURCE_ROOT; }; D124614517AC16820095F9D6 /* VVDSettingPanelWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VVDSettingPanelWindowController.m; path = "VVDocumenter-Xcode/Setting/VVDSettingPanelWindowController.m"; sourceTree = SOURCE_ROOT; }; D124614617AC16820095F9D6 /* VVDSettingPanelWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = VVDSettingPanelWindowController.xib; path = "VVDocumenter-Xcode/Setting/VVDSettingPanelWindowController.xib"; sourceTree = SOURCE_ROOT; }; D13EDDD71987F34C0029A555 /* VVSwiftFunctionCommenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVSwiftFunctionCommenter.h; sourceTree = ""; }; D13EDDD81987F34C0029A555 /* VVSwiftFunctionCommenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVSwiftFunctionCommenter.m; sourceTree = ""; }; D14070C318CE8819009B0EED /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; D14380F3179551B900C829CE /* VVDocumenter-Xcode.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "VVDocumenter-Xcode.xcplugin"; sourceTree = BUILT_PRODUCTS_DIR; }; D14380F6179551B900C829CE /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; D14380F9179551B900C829CE /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; D14380FA179551B900C829CE /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; D14380FB179551B900C829CE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; D14380FE179551B900C829CE /* VVDocumenter-Xcode-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "VVDocumenter-Xcode-Info.plist"; sourceTree = ""; }; D1438100179551B900C829CE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; D1438102179551B900C829CE /* VVDocumenter-Xcode-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VVDocumenter-Xcode-Prefix.pch"; sourceTree = ""; }; D16917DD17955C8D0036C06B /* VVDocumenterManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VVDocumenterManager.h; sourceTree = ""; }; D16917DE17955C8D0036C06B /* VVDocumenterManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VVDocumenterManager.m; sourceTree = ""; }; D16AFCD21796E088006719AA /* VVBaseCommenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVBaseCommenter.h; sourceTree = ""; }; D16AFCD31796E088006719AA /* VVBaseCommenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVBaseCommenter.m; sourceTree = ""; }; D16AFCD51796E09E006719AA /* VVPropertyCommenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVPropertyCommenter.h; sourceTree = ""; }; D16AFCD61796E09E006719AA /* VVPropertyCommenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVPropertyCommenter.m; sourceTree = ""; }; D16AFCD81796E0AC006719AA /* VVMethodCommenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVMethodCommenter.h; sourceTree = ""; }; D16AFCD91796E0AC006719AA /* VVMethodCommenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVMethodCommenter.m; sourceTree = ""; }; D16AFCDB1796E0B9006719AA /* VVFunctionCommenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVFunctionCommenter.h; sourceTree = ""; }; D16AFCDC1796E0B9006719AA /* VVFunctionCommenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVFunctionCommenter.m; sourceTree = ""; }; D16AFCDE1796E0C0006719AA /* VVMacroCommenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVMacroCommenter.h; sourceTree = ""; }; D16AFCDF1796E0C0006719AA /* VVMacroCommenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVMacroCommenter.m; sourceTree = ""; }; D16AFCE11796E0C9006719AA /* VVStructCommenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVStructCommenter.h; sourceTree = ""; }; D16AFCE21796E0C9006719AA /* VVStructCommenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVStructCommenter.m; sourceTree = ""; }; D16AFCE41796E0D0006719AA /* VVEnumCommenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVEnumCommenter.h; sourceTree = ""; }; D16AFCE51796E0D0006719AA /* VVEnumCommenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVEnumCommenter.m; sourceTree = ""; }; D16AFCE71796E0D6006719AA /* VVVariableCommenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVVariableCommenter.h; sourceTree = ""; }; D16AFCE81796E0D6006719AA /* VVVariableCommenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVVariableCommenter.m; sourceTree = ""; }; D1737635198A4C8A00FE2355 /* NSString+VVTextGetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+VVTextGetter.h"; sourceTree = ""; }; D1737636198A4C8A00FE2355 /* NSString+VVTextGetter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+VVTextGetter.m"; sourceTree = ""; }; D1737638198A4CF700FE2355 /* VVTextResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVTextResult.h; sourceTree = ""; }; D1737639198A4CF700FE2355 /* VVTextResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVTextResult.m; sourceTree = ""; }; D1986F73179A12BD00EA6643 /* CommenterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CommenterTests.m; sourceTree = ""; }; D1A6B1CE198A0D8600BCED83 /* VVSwiftPropertyCommenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVSwiftPropertyCommenter.h; sourceTree = ""; }; D1A6B1CF198A0D8600BCED83 /* VVSwiftPropertyCommenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVSwiftPropertyCommenter.m; sourceTree = ""; }; D1AC3B8D1796DB070063A484 /* VVDocumenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVDocumenter.h; sourceTree = ""; }; D1AC3B8E1796DB070063A484 /* VVDocumenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVDocumenter.m; sourceTree = ""; }; D1B316D5189A2AA700420A6E /* VVMethodTestsCode.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = VVMethodTestsCode.plist; sourceTree = ""; }; D1C462DA17999C2000EB7B23 /* VVDocumenterTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VVDocumenterTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; D1C462E017999C2000EB7B23 /* VVDocumenterTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "VVDocumenterTests-Info.plist"; sourceTree = ""; }; D1C462E217999C2000EB7B23 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; D1C462E517999C2000EB7B23 /* VVDocumenterTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VVDocumenterTests.m; sourceTree = ""; }; D1C462E717999C2000EB7B23 /* VVDocumenterTests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VVDocumenterTests-Prefix.pch"; sourceTree = ""; }; D1C462EB17999C9A00EB7B23 /* VVTestHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVTestHelper.h; sourceTree = ""; }; D1C462EC17999C9A00EB7B23 /* VVTestHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVTestHelper.m; sourceTree = ""; }; D1C462F017999CA200EB7B23 /* SyntaxTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SyntaxTests.m; sourceTree = ""; }; D1C462F317999CEC00EB7B23 /* NSString+VVSyntax.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+VVSyntax.h"; sourceTree = ""; }; D1C462F417999CEC00EB7B23 /* NSString+VVSyntax.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+VVSyntax.m"; sourceTree = ""; }; D1C6124619891B3700FDB554 /* VVSwiftEnumCommenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVSwiftEnumCommenter.h; sourceTree = ""; }; D1C6124719891B3700FDB554 /* VVSwiftEnumCommenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVSwiftEnumCommenter.m; sourceTree = ""; }; D1D66CA617A2AEF000E62F99 /* VVKeyboardEventSender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VVKeyboardEventSender.h; sourceTree = ""; }; D1D66CA717A2AEF000E62F99 /* VVKeyboardEventSender.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VVKeyboardEventSender.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ D14380F0179551B900C829CE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 893D8F8018262EF500E8A00C /* Carbon.framework in Frameworks */, D14380F7179551B900C829CE /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; D1C462D617999C2000EB7B23 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( D14070C418CE8819009B0EED /* XCTest.framework in Frameworks */, 53C67935184501030030C553 /* Carbon.framework in Frameworks */, D1C462DD17999C2000EB7B23 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ C4052CF51B3BB10700ED0CF0 /* ProjectHelper */ = { isa = PBXGroup; children = ( C4052CF61B3BB10700ED0CF0 /* VVProject.h */, C4052CF71B3BB10700ED0CF0 /* VVProject.m */, C4052CF81B3BB10700ED0CF0 /* VVWorkspaceManager.h */, C4052CF91B3BB10700ED0CF0 /* VVWorkspaceManager.m */, ); path = ProjectHelper; sourceTree = ""; }; D114BEDB179644D00043FA65 /* OCCategory */ = { isa = PBXGroup; children = ( D1737634198A4C5400FE2355 /* NSString+VVTextGetter */, D1C462F217999CEC00EB7B23 /* NSString+VVSyntax */, D114BEDC179644D00043FA65 /* NSString+PDRegex */, D114BEDF179644D00043FA65 /* NSTextView+VVTextGetter */, D1737638198A4CF700FE2355 /* VVTextResult.h */, D1737639198A4CF700FE2355 /* VVTextResult.m */, ); path = OCCategory; sourceTree = ""; }; D114BEDC179644D00043FA65 /* NSString+PDRegex */ = { isa = PBXGroup; children = ( D114BEDD179644D00043FA65 /* NSString+PDRegex.h */, D114BEDE179644D00043FA65 /* NSString+PDRegex.m */, ); path = "NSString+PDRegex"; sourceTree = ""; }; D114BEDF179644D00043FA65 /* NSTextView+VVTextGetter */ = { isa = PBXGroup; children = ( D114BEE1179644FA0043FA65 /* NSTextView+VVTextGetter.h */, D114BEE2179644FA0043FA65 /* NSTextView+VVTextGetter.m */, ); path = "NSTextView+VVTextGetter"; sourceTree = ""; }; D14380EA179551B900C829CE = { isa = PBXGroup; children = ( D14380FC179551B900C829CE /* VVDocumenter-Xcode */, D1C462DE17999C2000EB7B23 /* VVDocumenterTests */, D14380F5179551B900C829CE /* Frameworks */, D14380F4179551B900C829CE /* Products */, ); sourceTree = ""; }; D14380F4179551B900C829CE /* Products */ = { isa = PBXGroup; children = ( D14380F3179551B900C829CE /* VVDocumenter-Xcode.xcplugin */, D1C462DA17999C2000EB7B23 /* VVDocumenterTests.xctest */, ); name = Products; sourceTree = ""; }; D14380F5179551B900C829CE /* Frameworks */ = { isa = PBXGroup; children = ( D14070C318CE8819009B0EED /* XCTest.framework */, 893D8F7F18262EF500E8A00C /* Carbon.framework */, D14380F6179551B900C829CE /* Cocoa.framework */, D14380F8179551B900C829CE /* Other Frameworks */, ); name = Frameworks; sourceTree = ""; }; D14380F8179551B900C829CE /* Other Frameworks */ = { isa = PBXGroup; children = ( D14380F9179551B900C829CE /* AppKit.framework */, D14380FA179551B900C829CE /* CoreData.framework */, D14380FB179551B900C829CE /* Foundation.framework */, ); name = "Other Frameworks"; sourceTree = ""; }; D14380FC179551B900C829CE /* VVDocumenter-Xcode */ = { isa = PBXGroup; children = ( C4052CF51B3BB10700ED0CF0 /* ProjectHelper */, D193B8C917AC0C2400D2D76A /* Setting */, D1D66CA517A2AED700E62F99 /* KeyboardHelper */, D16AFCD11796E068006719AA /* Commenter */, D114BEDB179644D00043FA65 /* OCCategory */, D14380FD179551B900C829CE /* Supporting Files */, D16917DD17955C8D0036C06B /* VVDocumenterManager.h */, D16917DE17955C8D0036C06B /* VVDocumenterManager.m */, D1AC3B8D1796DB070063A484 /* VVDocumenter.h */, D1AC3B8E1796DB070063A484 /* VVDocumenter.m */, ); path = "VVDocumenter-Xcode"; sourceTree = ""; }; D14380FD179551B900C829CE /* Supporting Files */ = { isa = PBXGroup; children = ( D14380FE179551B900C829CE /* VVDocumenter-Xcode-Info.plist */, D1438102179551B900C829CE /* VVDocumenter-Xcode-Prefix.pch */, D14380FF179551B900C829CE /* InfoPlist.strings */, ); name = "Supporting Files"; sourceTree = ""; }; D16AFCD11796E068006719AA /* Commenter */ = { isa = PBXGroup; children = ( D11C542C17999D9000D3DE38 /* VVCommenter.h */, D11C542A17999D9000D3DE38 /* VVArgument.h */, D11C542B17999D9000D3DE38 /* VVArgument.m */, D16AFCD21796E088006719AA /* VVBaseCommenter.h */, D16AFCD31796E088006719AA /* VVBaseCommenter.m */, D16AFCD51796E09E006719AA /* VVPropertyCommenter.h */, D16AFCD61796E09E006719AA /* VVPropertyCommenter.m */, D16AFCD81796E0AC006719AA /* VVMethodCommenter.h */, D16AFCD91796E0AC006719AA /* VVMethodCommenter.m */, D16AFCDB1796E0B9006719AA /* VVFunctionCommenter.h */, D16AFCDC1796E0B9006719AA /* VVFunctionCommenter.m */, D13EDDD71987F34C0029A555 /* VVSwiftFunctionCommenter.h */, D13EDDD81987F34C0029A555 /* VVSwiftFunctionCommenter.m */, D1C6124619891B3700FDB554 /* VVSwiftEnumCommenter.h */, D1C6124719891B3700FDB554 /* VVSwiftEnumCommenter.m */, D1A6B1CE198A0D8600BCED83 /* VVSwiftPropertyCommenter.h */, D1A6B1CF198A0D8600BCED83 /* VVSwiftPropertyCommenter.m */, D16AFCDE1796E0C0006719AA /* VVMacroCommenter.h */, D16AFCDF1796E0C0006719AA /* VVMacroCommenter.m */, D16AFCE11796E0C9006719AA /* VVStructCommenter.h */, D16AFCE21796E0C9006719AA /* VVStructCommenter.m */, D16AFCE41796E0D0006719AA /* VVEnumCommenter.h */, D16AFCE51796E0D0006719AA /* VVEnumCommenter.m */, D16AFCE71796E0D6006719AA /* VVVariableCommenter.h */, D16AFCE81796E0D6006719AA /* VVVariableCommenter.m */, 4B50A26E1B315CF3008A4400 /* VVSwiftExtensionCommenter.h */, 4B50A26F1B315CF3008A4400 /* VVSwiftExtensionCommenter.m */, ); path = Commenter; sourceTree = ""; }; D1737634198A4C5400FE2355 /* NSString+VVTextGetter */ = { isa = PBXGroup; children = ( D1737635198A4C8A00FE2355 /* NSString+VVTextGetter.h */, D1737636198A4C8A00FE2355 /* NSString+VVTextGetter.m */, ); path = "NSString+VVTextGetter"; sourceTree = ""; }; D193B8C917AC0C2400D2D76A /* Setting */ = { isa = PBXGroup; children = ( D124614217AC16820095F9D6 /* VVDocumenterSetting.h */, D124614317AC16820095F9D6 /* VVDocumenterSetting.m */, D124614417AC16820095F9D6 /* VVDSettingPanelWindowController.h */, D124614517AC16820095F9D6 /* VVDSettingPanelWindowController.m */, D124614617AC16820095F9D6 /* VVDSettingPanelWindowController.xib */, ); name = Setting; path = SettingPanel; sourceTree = ""; }; D1986F71179A12BD00EA6643 /* CommenterTests */ = { isa = PBXGroup; children = ( D1986F73179A12BD00EA6643 /* CommenterTests.m */, ); path = CommenterTests; sourceTree = ""; }; D1B316D2189A2A5900420A6E /* DocumenterTests */ = { isa = PBXGroup; children = ( D1B316D5189A2AA700420A6E /* VVMethodTestsCode.plist */, ); path = DocumenterTests; sourceTree = ""; }; D1C462DE17999C2000EB7B23 /* VVDocumenterTests */ = { isa = PBXGroup; children = ( D1B316D2189A2A5900420A6E /* DocumenterTests */, D1986F71179A12BD00EA6643 /* CommenterTests */, D1C462EE17999CA200EB7B23 /* SyntaxTests */, D1C462EB17999C9A00EB7B23 /* VVTestHelper.h */, D1C462EC17999C9A00EB7B23 /* VVTestHelper.m */, D1C462E517999C2000EB7B23 /* VVDocumenterTests.m */, D1C462DF17999C2000EB7B23 /* Supporting Files */, ); path = VVDocumenterTests; sourceTree = ""; }; D1C462DF17999C2000EB7B23 /* Supporting Files */ = { isa = PBXGroup; children = ( D1C462E017999C2000EB7B23 /* VVDocumenterTests-Info.plist */, D1C462E117999C2000EB7B23 /* InfoPlist.strings */, D1C462E717999C2000EB7B23 /* VVDocumenterTests-Prefix.pch */, ); name = "Supporting Files"; sourceTree = ""; }; D1C462EE17999CA200EB7B23 /* SyntaxTests */ = { isa = PBXGroup; children = ( D1C462F017999CA200EB7B23 /* SyntaxTests.m */, ); path = SyntaxTests; sourceTree = ""; }; D1C462F217999CEC00EB7B23 /* NSString+VVSyntax */ = { isa = PBXGroup; children = ( D1C462F317999CEC00EB7B23 /* NSString+VVSyntax.h */, D1C462F417999CEC00EB7B23 /* NSString+VVSyntax.m */, ); path = "NSString+VVSyntax"; sourceTree = ""; }; D1D66CA517A2AED700E62F99 /* KeyboardHelper */ = { isa = PBXGroup; children = ( D1D66CA617A2AEF000E62F99 /* VVKeyboardEventSender.h */, D1D66CA717A2AEF000E62F99 /* VVKeyboardEventSender.m */, ); path = KeyboardHelper; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ D14380F2179551B900C829CE /* VVDocumenter-Xcode */ = { isa = PBXNativeTarget; buildConfigurationList = D1438105179551B900C829CE /* Build configuration list for PBXNativeTarget "VVDocumenter-Xcode" */; buildPhases = ( D14380EF179551B900C829CE /* Sources */, D14380F0179551B900C829CE /* Frameworks */, D14380F1179551B900C829CE /* Resources */, ); buildRules = ( ); dependencies = ( ); name = "VVDocumenter-Xcode"; productName = "VVDocumenter-Xcode"; productReference = D14380F3179551B900C829CE /* VVDocumenter-Xcode.xcplugin */; productType = "com.apple.product-type.bundle"; }; D1C462D917999C2000EB7B23 /* VVDocumenterTests */ = { isa = PBXNativeTarget; buildConfigurationList = D1C462EA17999C2000EB7B23 /* Build configuration list for PBXNativeTarget "VVDocumenterTests" */; buildPhases = ( D1C462D517999C2000EB7B23 /* Sources */, D1C462D617999C2000EB7B23 /* Frameworks */, D1C462D717999C2000EB7B23 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = VVDocumenterTests; productName = VVDocumenterTests; productReference = D1C462DA17999C2000EB7B23 /* VVDocumenterTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ D14380EB179551B900C829CE /* Project object */ = { isa = PBXProject; attributes = { LastTestingUpgradeCheck = 0510; LastUpgradeCheck = 0700; ORGANIZATIONNAME = "OneV's Den"; }; buildConfigurationList = D14380EE179551B900C829CE /* Build configuration list for PBXProject "VVDocumenter-Xcode" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = D14380EA179551B900C829CE; productRefGroup = D14380F4179551B900C829CE /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( D14380F2179551B900C829CE /* VVDocumenter-Xcode */, D1C462D917999C2000EB7B23 /* VVDocumenterTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ D14380F1179551B900C829CE /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( D1438101179551B900C829CE /* InfoPlist.strings in Resources */, D124614917AC16820095F9D6 /* VVDSettingPanelWindowController.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; D1C462D717999C2000EB7B23 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( D1B316D6189A2AA700420A6E /* VVMethodTestsCode.plist in Resources */, D1C462E317999C2000EB7B23 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ D14380EF179551B900C829CE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( D18224DC17956290001A5E8A /* VVDocumenterManager.m in Sources */, D114BEE0179644D00043FA65 /* NSString+PDRegex.m in Sources */, D114BEE3179644FA0043FA65 /* NSTextView+VVTextGetter.m in Sources */, D1AC3B8F1796DB070063A484 /* VVDocumenter.m in Sources */, D16AFCD41796E088006719AA /* VVBaseCommenter.m in Sources */, 4B50A2701B315CF3008A4400 /* VVSwiftExtensionCommenter.m in Sources */, D1A6B1D0198A0D8600BCED83 /* VVSwiftPropertyCommenter.m in Sources */, D16AFCD71796E09E006719AA /* VVPropertyCommenter.m in Sources */, D16AFCDA1796E0AC006719AA /* VVMethodCommenter.m in Sources */, D16AFCDD1796E0B9006719AA /* VVFunctionCommenter.m in Sources */, D13EDDD91987F34C0029A555 /* VVSwiftFunctionCommenter.m in Sources */, D16AFCE01796E0C0006719AA /* VVMacroCommenter.m in Sources */, D16AFCE31796E0C9006719AA /* VVStructCommenter.m in Sources */, D16AFCE61796E0D0006719AA /* VVEnumCommenter.m in Sources */, D16AFCE91796E0D6006719AA /* VVVariableCommenter.m in Sources */, D1C462F517999CEC00EB7B23 /* NSString+VVSyntax.m in Sources */, D1737637198A4C8A00FE2355 /* NSString+VVTextGetter.m in Sources */, C4052CFA1B3BB10700ED0CF0 /* VVProject.m in Sources */, D1C6124819891B3700FDB554 /* VVSwiftEnumCommenter.m in Sources */, D11C542D17999D9000D3DE38 /* VVArgument.m in Sources */, D1D66CA817A2AEF000E62F99 /* VVKeyboardEventSender.m in Sources */, D173763A198A4CF700FE2355 /* VVTextResult.m in Sources */, D124614717AC16820095F9D6 /* VVDocumenterSetting.m in Sources */, C4052CFB1B3BB10700ED0CF0 /* VVWorkspaceManager.m in Sources */, D124614817AC16820095F9D6 /* VVDSettingPanelWindowController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; D1C462D517999C2000EB7B23 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( C4052CFC1B3BB2C200ED0CF0 /* VVProject.m in Sources */, C4052CFD1B3BB2C200ED0CF0 /* VVWorkspaceManager.m in Sources */, 4B06DF741B315E9D007D69BE /* VVSwiftExtensionCommenter.m in Sources */, D173763B198A53C000FE2355 /* NSString+VVTextGetter.m in Sources */, D173763C198A53C000FE2355 /* VVTextResult.m in Sources */, D14110B81988C14500A7083F /* VVDocumenterSetting.m in Sources */, D14110B91988C14500A7083F /* VVDSettingPanelWindowController.m in Sources */, D14110B21988C12F00A7083F /* VVKeyboardEventSender.m in Sources */, D14110B31988C12F00A7083F /* NSString+VVSyntax.m in Sources */, D14110B41988C12F00A7083F /* NSString+PDRegex.m in Sources */, D1A6B1D1198A0D8600BCED83 /* VVSwiftPropertyCommenter.m in Sources */, D14110B51988C12F00A7083F /* NSTextView+VVTextGetter.m in Sources */, D14110B61988C12F00A7083F /* VVDocumenterManager.m in Sources */, D14110B71988C12F00A7083F /* VVDocumenter.m in Sources */, D14110A81988C12000A7083F /* VVArgument.m in Sources */, D1C6124919891B3700FDB554 /* VVSwiftEnumCommenter.m in Sources */, D14110A91988C12000A7083F /* VVBaseCommenter.m in Sources */, D14110AA1988C12000A7083F /* VVPropertyCommenter.m in Sources */, D14110AB1988C12000A7083F /* VVMethodCommenter.m in Sources */, D14110AC1988C12000A7083F /* VVFunctionCommenter.m in Sources */, D14110AD1988C12000A7083F /* VVSwiftFunctionCommenter.m in Sources */, D14110AE1988C12000A7083F /* VVMacroCommenter.m in Sources */, D14110AF1988C12000A7083F /* VVStructCommenter.m in Sources */, D14110B01988C12000A7083F /* VVEnumCommenter.m in Sources */, D14110B11988C12000A7083F /* VVVariableCommenter.m in Sources */, D14110A71988C08700A7083F /* VVDocumenterTests.m in Sources */, D14110A61988C07E00A7083F /* VVTestHelper.m in Sources */, D1C462F117999CA200EB7B23 /* SyntaxTests.m in Sources */, D1986F74179A12BD00EA6643 /* CommenterTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ D14380FF179551B900C829CE /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( D1438100179551B900C829CE /* en */, ); name = InfoPlist.strings; sourceTree = ""; }; D1C462E117999C2000EB7B23 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( D1C462E217999C2000EB7B23 /* en */, ); name = InfoPlist.strings; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ D1438103179551B900C829CE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.8; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; }; name = Debug; }; D1438104179551B900C829CE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.8; SDKROOT = macosx; }; name = Release; }; D1438106179551B900C829CE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; COMBINE_HIDPI_IMAGES = YES; DEPLOYMENT_LOCATION = YES; DSTROOT = "${HOME}"; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_ENABLE_OBJC_GC = unsupported; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "VVDocumenter-Xcode/VVDocumenter-Xcode-Prefix.pch"; INFOPLIST_FILE = "VVDocumenter-Xcode/VVDocumenter-Xcode-Info.plist"; INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; PRODUCT_BUNDLE_IDENTIFIER = "com.onevcat.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = xcplugin; }; name = Debug; }; D1438107179551B900C829CE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; COMBINE_HIDPI_IMAGES = YES; DEPLOYMENT_LOCATION = YES; DSTROOT = "${HOME}"; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_ENABLE_OBJC_GC = unsupported; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "VVDocumenter-Xcode/VVDocumenter-Xcode-Prefix.pch"; INFOPLIST_FILE = "VVDocumenter-Xcode/VVDocumenter-Xcode-Info.plist"; INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.onevcat.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = xcplugin; }; name = Release; }; D1C462E817999C2000EB7B23 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; COMBINE_HIDPI_IMAGES = YES; FRAMEWORK_SEARCH_PATHS = ( "$(DEVELOPER_DIR)/../SharedFrameworks", "$(DEVELOPER_LIBRARY_DIR)/Frameworks", "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "VVDocumenterTests/VVDocumenterTests-Prefix.pch"; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, ); INFOPLIST_FILE = "VVDocumenterTests/VVDocumenterTests-Info.plist"; PRODUCT_BUNDLE_IDENTIFIER = "com.onevcat.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; D1C462E917999C2000EB7B23 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; COMBINE_HIDPI_IMAGES = YES; FRAMEWORK_SEARCH_PATHS = ( "$(DEVELOPER_DIR)/../SharedFrameworks", "$(DEVELOPER_LIBRARY_DIR)/Frameworks", "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "VVDocumenterTests/VVDocumenterTests-Prefix.pch"; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, ); INFOPLIST_FILE = "VVDocumenterTests/VVDocumenterTests-Info.plist"; ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.onevcat.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ D14380EE179551B900C829CE /* Build configuration list for PBXProject "VVDocumenter-Xcode" */ = { isa = XCConfigurationList; buildConfigurations = ( D1438103179551B900C829CE /* Debug */, D1438104179551B900C829CE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; D1438105179551B900C829CE /* Build configuration list for PBXNativeTarget "VVDocumenter-Xcode" */ = { isa = XCConfigurationList; buildConfigurations = ( D1438106179551B900C829CE /* Debug */, D1438107179551B900C829CE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; D1C462EA17999C2000EB7B23 /* Build configuration list for PBXNativeTarget "VVDocumenterTests" */ = { isa = XCConfigurationList; buildConfigurations = ( D1C462E817999C2000EB7B23 /* Debug */, D1C462E917999C2000EB7B23 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = D14380EB179551B900C829CE /* Project object */; } ================================================ FILE: VVDocumenter-Xcode.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: VVDocumenter-Xcode.xcodeproj/xcshareddata/xcschemes/VVDocumenter-Xcode.xcscheme ================================================ ================================================ FILE: VVDocumenter-Xcode.xcodeproj/xcshareddata/xcschemes/VVDocumenterTests.xcscheme ================================================ ================================================ FILE: VVDocumenterTests/CommenterTests/CommenterTests.m ================================================ // // CommenterTests.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-20. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import "VVCommenter.h" @interface CommenterTests : XCTestCase @end @implementation CommenterTests - (void)setUp { [super setUp]; // Set-up code here. } - (void)tearDown { // Tear-down code here. [super tearDown]; } - (void) testArgumentType { VVArgument *arg = [[VVArgument alloc] init]; arg.type = @" int "; XCTAssertEqualObjects(arg.type, @"int", @"%@",arg.type); arg.type = @"char *"; XCTAssertEqualObjects(arg.type, @"char", @"%@",arg.type); arg.type = @"NSString *"; XCTAssertEqualObjects(arg.type, @"NSString", @"%@",arg.type); } - (void) testArgumentName { VVArgument *arg = [[VVArgument alloc] init]; arg.name = @"*argv[]"; XCTAssertEqualObjects(arg.name, @"argv", @"%@",arg.name); arg.name = @"**a"; XCTAssertEqualObjects(arg.name, @"a", @"%@",arg.name); } - (void) testArgumentEquals { VVArgument *argA = [[VVArgument alloc] init]; argA.name = @"a"; argA.type = @"NSString"; VVArgument *argB = [[VVArgument alloc] init]; argB.name = @"b"; argB.type = @"NSString"; VVArgument *argC = [[VVArgument alloc] init]; argC.name = @"a"; argC.type = @"NSString"; XCTAssertEqualObjects(argA, argA); XCTAssertNotEqualObjects(argA, argB); XCTAssertEqualObjects(argA, argC); } -(void) testParseArguments { VVBaseCommenter *baseCommenter = [[VVFunctionCommenter alloc] initWithIndentString:@"" codeString:@""]; baseCommenter.code = @"void dosomething( int x, int y );"; [baseCommenter document]; VVArgument *arg0 = [[VVArgument alloc] init]; arg0.type = @"int"; arg0.name = @"x"; VVArgument *arg1 = [[VVArgument alloc] init]; arg1.type = @"int"; arg1.name = @"y"; NSUInteger count = baseCommenter.arguments.count; XCTAssertEqual(count, (NSUInteger)2, @"There should be 2 args, %@", baseCommenter.arguments); XCTAssertEqualObjects(arg0, baseCommenter.arguments[0]); XCTAssertEqualObjects(arg1, baseCommenter.arguments[1]); } - (void) testParseVarArguments { VVBaseCommenter *baseCommenter = [[VVFunctionCommenter alloc] initWithIndentString:@"" codeString:@""]; baseCommenter.code = @"int main(int argc, char *argv[]) \n {"; [baseCommenter document]; VVArgument *arg0 = [[VVArgument alloc] init]; arg0.type = @"int"; arg0.name = @"argc"; VVArgument *arg1 = [[VVArgument alloc] init]; arg1.type = @"char"; arg1.name = @"argv"; NSUInteger count = baseCommenter.arguments.count; XCTAssertEqual(count, (NSUInteger)2, @"There should be 2 args, %@", baseCommenter.arguments); XCTAssertEqualObjects(arg0, baseCommenter.arguments[0]); XCTAssertEqualObjects(arg1, baseCommenter.arguments[1]); } - (void) testParseAttributedFunction { VVBaseCommenter *baseCommenter = [[VVFunctionCommenter alloc] initWithIndentString:@"" codeString:@""]; baseCommenter.code = @"void dosomething( int x ) __attribute__((const));"; [baseCommenter document]; VVArgument *arg0 = [[VVArgument alloc] init]; arg0.type = @"int"; arg0.name = @"x"; NSUInteger count = baseCommenter.arguments.count; XCTAssertEqual(count, (NSUInteger)1, @"There should be one arg, %@", baseCommenter.arguments); XCTAssertEqualObjects(arg0, baseCommenter.arguments[0]); } @end ================================================ FILE: VVDocumenterTests/DocumenterTests/VVMethodTestsCode.plist ================================================ vv_isObjCMethod source - (id)initWithDuration:(CFTimeInterval)duration sourceRect:(CGRect)sourceRect { uniform -(id)initWithDuration:(CFTimeInterval)duration sourceRect:(CGRect)sourceRect { result /** * <#Description#> * * @param duration <#duration description#> * @param sourceRect <#sourceRect description#> * * @return <#return value description#> */ source - (BOOL) application: (UIApplication *) application didFinishLaunchingWithOptions: (NSDictionary *) launchOptions; uniform -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; result /** * <#Description#> * * @param application <#application description#> * @param launchOptions <#launchOptions description#> * * @return <#return value description#> */ source + (ADTransition *)nullTransition; uniform +(ADTransition *)nullTransition; result /** * <#Description#> * * @return <#return value description#> */ source -(void)whenLinked:(void (^)(void))actionHandler uniform -(void)whenLinked:(void(^)(void))actionHandler result /** * <#Description#> * * @param actionHandler <#actionHandler description#> */ source -(void) writeMediasetJSON: (void (^)(void)) uploadCompletionBlock{} uniform -(void)writeMediasetJSON:(void(^)(void))uploadCompletionBlock{} result /** * <#Description#> * * @param uploadCompletionBlock <#uploadCompletionBlock description#> */ source -(void) createNewMediaset:(NSString *) collectionName withCompletionBlock: (void (^)(void)) completionBlock; uniform -(void)createNewMediaset:(NSString *)collectionName withCompletionBlock:(void(^)(void))completionBlock; result /** * <#Description#> * * @param collectionName <#collectionName description#> * @param completionBlock <#completionBlock description#> */ vv_isCFunction source int square(int n) __attribute__((const)); uniform int square(int n)__attribute__((const)); result /** * <#Description#> * * @param n <#n description#> * * @return <#return value description#> */ source void dosomething ( int x, int y ); uniform void dosomething( int x, int y ); result /** * <#Description#> * * @param x <#x description#> * @param y <#y description#> */ source int main(int argc, char *argv[]) { uniform int main(int argc, char *argv[]){ result /** * <#Description#> * * @param argc <#argc description#> * @param argv <#argv description#> * * @return <#return value description#> */ source void NoParamFunc(); uniform void NoParamFunc(); result /** * <#Description#> */ source typedef void(^IBLShareSuccessBlock)(ShareType type, SSPublishContentState state, id<ISSStatusInfo> statusInfo, BOOL end); uniform typedef void(^IBLShareSuccessBlock)(ShareType type, SSPublishContentState state, id<ISSStatusInfo> statusInfo, BOOL end); result /** * <#Description#> * * @param type <#type description#> * @param state <#state description#> * @param statusInfo <#statusInfo description#> * @param end <#end description#> */ source typedef NSURL * (^AFURLSessionDownloadTaskDidFinishDownloadingBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location); uniform typedef NSURL *(^AFURLSessionDownloadTaskDidFinishDownloadingBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location); result /** * <#Description#> * * @param session <#session description#> * @param downloadTask <#downloadTask description#> * @param location <#location description#> * * @return <#return value description#> */ source typedef void (^AFURLSessionDownloadTaskDidResumeBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes); uniform typedef void(^AFURLSessionDownloadTaskDidResumeBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes); result /** * <#Description#> * * @param session <#session description#> * @param downloadTask <#downloadTask description#> * @param fileOffset <#fileOffset description#> * @param expectedTotalBytes <#expectedTotalBytes description#> */ source typedef void (^HelloBlock)(void); uniform typedef void(^HelloBlock)(void); result /** * <#Description#> */ source virtual void run(RegridMethod method, int timeLevel, const RLLVelocityField &f, const SpaceCoord &x, SphereVelocity &y, RLLMeshIndex *idx = NULL); uniform virtual void run(RegridMethod method, int timeLevel, const RLLVelocityField &f, const SpaceCoord &x, SphereVelocity &y, RLLMeshIndex *idx = NULL); result /** * <#Description#> * * @param method <#method description#> * @param timeLevel <#timeLevel description#> * @param f <#f description#> * @param x <#x description#> * @param y <#y description#> * @param idx <#idx description#> */ source void print2DList(int rowCount, int (*p)[10]); uniform void print2DList(int rowCount, int(*p)[10]); result /** * <#Description#> * * @param rowCount <#rowCount description#> * @param p <#p description#> */ vv_isProperty source @property (nonatomic, copy ) NSString *code; uniform @property(nonatomic, copy )NSString *code; result /** * <#Description#> */ source @property ( nonatomic, strong ) Miao* test; uniform @property( nonatomic, strong )Miao* test; result /** * <#Description#> */ source @property ( assign, strong ) int test; uniform @property( assign, strong )int test; result /** * <#Description#> */ vv_isMacro source #define MAX(A,B) ({ uniform #define MAX(A,B)({ result /** * <#Description#> * * @param A <#A description#> * @param B <#B description#> * * @return <#return value description#> */ source #define MIN(A,B) ((A) < (B) ? (A) : (B)) uniform #define MIN(A,B)((A)<(B)?(A):(B)) result /** * <#Description#> * * @param A <#A description#> * @param B <#B description#> * * @return <#return value description#> */ source #define ABS(A) ((A) < 0 ? (-(A)) : (A)) uniform #define ABS(A)((A)< 0 ?(-(A)):(A)) result /** * <#Description#> * * @param A <#A description#> * * @return <#return value description#> */ vv_isStruct source struct Foo { uniform struct Foo { result /** * <#Description#> */ source struct node { uniform struct node { result /** * <#Description#> */ source struct objc_object { uniform struct objc_object { result /** * <#Description#> */ vv_isEnum source typedef NS_ENUM(NSInteger, SIAlertViewBackgroundStyle) { SIAlertViewBackgroundStyleGradient = 0, SIAlertViewBackgroundStyleSolid, }; uniform typedef NS_ENUM(NSInteger, SIAlertViewBackgroundStyle){ SIAlertViewBackgroundStyleGradient = 0, SIAlertViewBackgroundStyleSolid, }; result /** * <#Description#> */ typedef NS_ENUM(NSInteger, SIAlertViewBackgroundStyle) { /** * <#Description#> */ SIAlertViewBackgroundStyleGradient = 0, /** * <#Description#> */ SIAlertViewBackgroundStyleSolid, }; vv_isComplieKeyword source @interface VVDocumenter : NSObject { uniform @interface VVDocumenter : NSObject { result /** * <#Description#> */ source @interface VVDocumenter : NSObject { uniform @interface VVDocumenter : NSObject { result /** * <#Description#> */ source @interface SyntaxTests() @property (nonatomic, retain) NSArray* inputs; uniform @interface SyntaxTests()@property(nonatomic, retain)NSArray* inputs; result /** * <#Description#> */ source @implementation SyntaxTests - (void)setUp { uniform @implementation SyntaxTests -(void)setUp { result /** * <#Description#> */ source @interface A (a) - (id) foo; uniform @interface A(a)-(id)foo; result /** * <#Description#> */ vv_isSwiftFunction source func testParasType(var a: Int, let b: Int, inout c: Int, d: Int) { uniform func testParasType(var a: Int, let b: Int, inout c: Int, d: Int){ result /** <#Description#> - parameter a: <#a description#> - parameter b: <#b description#> - parameter c: <#c description#> - parameter d: <#d description#> */ source func sayHello(personName: String) -> String { uniform func sayHello(personName: String)-> String { result /** <#Description#> - parameter personName: <#personName description#> - returns: <#return value description#> */ source func go(para: Int -> String) -> (String -> String) { uniform func go(para: Int -> String)->(String -> String){ result /** <#Description#> - parameter para: <#para description#> - returns: <#return value description#> */ source public func go (miao: Int, wu: String) -> Void { uniform public func go(miao: Int, wu: String)-> Void { result /** <#Description#> - parameter miao: <#miao description#> - parameter wu: <#wu description#> */ source init(style: Style, _ gearing: Gearing, #handlebar: Handlebar, frameSize centimeters: Int = 1) { uniform init(style: Style, _ gearing: Gearing, #handlebar: Handlebar, frameSize centimeters: Int = 1){ result /** <#Description#> - parameter style: <#style description#> - parameter gearing: <#gearing description#> - parameter handlebar: <#handlebar description#> - parameter centimeters: <#centimeters description#> - returns: <#return value description#> */ source func Test(input : Int, condition : (Int, String) -> Bool = {(t: Int,k: String) in return true}) -> (Int,Int) { uniform func Test(input : Int, condition :(Int, String)-> Bool = {(t: Int,k: String)in return true})->(Int,Int){ result /** <#Description#> - parameter input: <#input description#> - parameter condition: <#condition description#> - returns: <#return value description#> */ source func URLSession(session: NSURLSession!, task: NSURLSessionTask!, didReceiveChallenge challenge: NSURLAuthenticationChallenge!, completionHandler: ((NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void)!) { uniform func URLSession(session: NSURLSession!, task: NSURLSessionTask!, didReceiveChallenge challenge: NSURLAuthenticationChallenge!, completionHandler:((NSURLSessionAuthChallengeDisposition, NSURLCredential!)-> Void)!){ result /** <#Description#> - parameter session: <#session description#> - parameter task: <#task description#> - parameter challenge: <#challenge description#> - parameter completionHandler: <#completionHandler description#> */ source func makeTuple(a:Int, b:Int, c:Int) -> (sum:Int, product:Int, max:Int) { uniform func makeTuple(a:Int, b:Int, c:Int)->(sum:Int, product:Int, max:Int){ result /** <#Description#> - parameter a: <#a description#> - parameter b: <#b description#> - parameter c: <#c description#> - returns: <#return value description#> */ source public subscript (key: KeyType) -> ValueType? { uniform public subscript(key: KeyType)-> ValueType? { result /** <#Description#> - parameter key: <#key description#> - returns: <#return value description#> */ source func getSomething(input:String?, success: (Int) -> Void, failure: (NSHTTPURLResponse?, AnyObject?, NSError?) -> Void) { uniform func getSomething(input:String?, success:(Int)-> Void, failure:(NSHTTPURLResponse?, AnyObject?, NSError?)-> Void){ result /** <#Description#> - parameter input: <#input description#> - parameter success: <#success description#> - parameter failure: <#failure description#> */ source func methodCouldThrows(count: Int) throws -> Int { uniform func methodCouldThrows(count: Int)throws -> Int { result /** <#Description#> - parameter count: <#count description#> - throws: <#throws value description#> - returns: <#return value description#> */ source func methodCouldThrows() throws { uniform func methodCouldThrows()throws { result /** <#Description#> - throws: <#throws value description#> */ source func methodCouldThrows(count: Int, name: String, f: (Int, String) throws -> Void) rethrows -> Int { uniform func methodCouldThrows(count: Int, name: String, f:(Int, String)throws -> Void)rethrows -> Int { result /** <#Description#> - parameter count: <#count description#> - parameter name: <#name description#> - parameter f: <#f description#> - throws: <#throws value description#> - returns: <#return value description#> */ source public class func amethod(count: Int) -> Int? { uniform public class func amethod(count: Int)-> Int? { result /** <#Description#> - parameter count: <#count description#> - returns: <#return value description#> */ source func testTuple(aTuple: (first: String, second: String, third: String)) -> (first: String, second: String, third: String)? { uniform func testTuple(aTuple:(first: String, second: String, third: String))->(first: String, second: String, third: String)? { result /** <#Description#> - parameter aTuple: <#aTuple description#> - returns: <#return value description#> */ vv_isSwiftEnum source enum Handlebar { case Riser, Café, Drop, Bullhorn } uniform enum Handlebar { case Riser, Café, Drop, Bullhorn } result /** <#Description#> - Riser: <#Riser description#> - Café: <#Café description#> - Drop: <#Drop description#> - Bullhorn: <#Bullhorn description#> */ source public enum Gearing { case Fixed case Freewheel(speeds: Int) } uniform public enum Gearing { case Fixed case Freewheel(speeds: Int)} result /** <#Description#> - Fixed: <#Fixed description#> - Freewheel: <#Freewheel description#> */ source enum ASCIIControlCharacter: Character { case Tab = "\t" case LineFeed = "\n" case CarriageReturn = "\r" } uniform enum ASCIIControlCharacter: Character { case Tab = "\t" case LineFeed = "\n" case CarriageReturn = "\r" } result /** <#Description#> - Tab: <#Tab description#> - LineFeed: <#LineFeed description#> - CarriageReturn: <#CarriageReturn description#> */ source enum Planet: Int { case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune } uniform enum Planet: Int { case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune } result /** <#Description#> - Mercury: <#Mercury description#> - Venus: <#Venus description#> - Earth: <#Earth description#> - Mars: <#Mars description#> - Jupiter: <#Jupiter description#> - Saturn: <#Saturn description#> - Uranus: <#Uranus description#> - Neptune: <#Neptune description#> */ source enum Barcode { case UPCA(Int, Int, Int, Int) case QRCode(String) } uniform enum Barcode { case UPCA(Int, Int, Int, Int)case QRCode(String)} result /** <#Description#> - UPCA: <#UPCA description#> - QRCode: <#QRCode description#> */ vv_isSwiftProperty source let handlebar: Handlebar uniform let handlebar: Handlebar result /// <#Description#> vv_isSwiftExtension source extension MyClass: SomeDelegate { uniform extension MyClass: SomeDelegate { result // MARK: - <#SomeDelegate#> source private extension MyClass\n { uniform private extension MyClass\n { result // MARK: - <#Description#> ================================================ FILE: VVDocumenterTests/SyntaxTests/SyntaxTests.m ================================================ // // SyntaxTests.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-19. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import "VVTestHelper.h" #import "NSString+VVSyntax.h" @interface SyntaxTests : XCTestCase @property (nonatomic, strong) NSArray* inputs; @property (nonatomic, strong) NSArray* corrects; @end @implementation SyntaxTests - (void)setUp { [super setUp]; // Set-up code here. self.inputs = [VVTestHelper testCodes]; self.corrects = [VVTestHelper uniformCodes]; } - (void)tearDown { // Tear-down code here. self.inputs = nil; self.corrects = nil; [super tearDown]; } -(void) testStringByConvertingToUniform { for (int i = 0; i < (int)[self.inputs count]; i++) { for (int j = 0; j < [self.inputs[i] count]; j++) { NSString *converted = [self.inputs[i][j] vv_stringByConvertingToUniform]; NSString *result = self.corrects[i][j]; XCTAssertTrue([result isEqualToString:converted], @"%@ should be the same as %@", converted, result); } } } -(void) testIsObjCMethod { NSArray *boolResult = @[@YES,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO]; for (int i = 0; i < (int)[self.inputs count]; i++) { for (int j = 0; j < [self.inputs[i] count]; j++) { NSString *result = self.corrects[i][j]; XCTAssertTrue([result vv_isObjCMethod] == [boolResult[i] boolValue], @"%@ should %@ be a ObjC method", result, [boolResult[i] boolValue] ? @"" : @"not"); } } } -(void) testIsCFunction { NSArray *boolResult = @[@NO,@YES,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO]; for (int i = 0; i < (int)[self.inputs count]; i++) { for (int j = 0; j < [self.inputs[i] count]; j++) { NSString *result = self.corrects[i][j]; XCTAssertTrue([result vv_isCFunction] == [boolResult[i] boolValue], @"%@ should %@ be a C function", result, [boolResult[i] boolValue] ? @"" : @"not"); } } } -(void) testIsProperty { NSArray *boolResult = @[@NO,@NO,@YES,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO]; for (int i = 0; i < (int)[self.inputs count]; i++) { for (int j = 0; j < [self.inputs[i] count]; j++) { NSString *result = self.corrects[i][j]; XCTAssertTrue([result vv_isProperty] == [boolResult[i] boolValue], @"%@ should %@ be a property", result, [boolResult[i] boolValue] ? @"" : @"not"); } } } -(void) testIsMacro { NSArray *boolResult = @[@NO,@NO,@NO,@YES,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO]; for (int i = 0; i < (int)[self.inputs count]; i++) { for (int j = 0; j < [self.inputs[i] count]; j++) { NSString *result = self.corrects[i][j]; XCTAssertTrue([result vv_isMacro] == [boolResult[i] boolValue], @"%@ should %@ be a macro", result, [boolResult[i] boolValue] ? @"" : @"not"); } } } -(void) testIsStruct { NSArray *boolResult = @[@NO,@NO,@NO,@NO,@YES,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO]; for (int i = 0; i < (int)[self.inputs count]; i++) { for (int j = 0; j < [self.inputs[i] count]; j++) { NSString *result = self.corrects[i][j]; XCTAssertTrue([result vv_isStruct] == [boolResult[i] boolValue], @"%@ should %@ be a struct", result, [boolResult[i] boolValue] ? @"" : @"not"); } } } -(void) testIsEnum { NSArray *boolResult = @[@NO,@NO,@NO,@NO,@NO,@YES,@NO,@NO,@NO,@NO,@NO,@NO,@NO]; for (int i = 0; i < (int)[self.inputs count]; i++) { for (int j = 0; j < [self.inputs[i] count]; j++) { NSString *result = self.corrects[i][j]; XCTAssertTrue([result vv_isEnum] == [boolResult[i] boolValue], @"%@ should %@ be a enum", result, [boolResult[i] boolValue] ? @"" : @"not"); } } } -(void) testIsUnion { NSArray *boolResult = @[@NO,@NO,@NO,@NO,@NO,@NO,@YES,@NO,@NO,@NO,@NO,@NO,@NO]; for (int i = 0; i < (int)[self.inputs count]; i++) { for (int j = 0; j < [self.inputs[i] count]; j++) { NSString *result = self.corrects[i][j]; XCTAssertTrue([result vv_isUnion] == [boolResult[i] boolValue], @"%@ should %@ be a union", result, [boolResult[i] boolValue] ? @"" : @"not"); } } } -(void) testIsCompileKeyword { NSArray *boolResult = @[@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@YES,@NO,@NO,@NO,@NO]; for (int i = 0; i < (int)[self.inputs count]; i++) { for (int j = 0; j < [self.inputs[i] count]; j++) { NSString *result = self.corrects[i][j]; XCTAssertTrue([result vv_isComplieKeyword] == [boolResult[i] boolValue], @"%@ should %@ be a complie keyword", result, [boolResult[i] boolValue] ? @"" : @"not"); } } } -(void) testIsSwiftFunction { NSArray *boolResult = @[@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@YES,@NO,@NO,@NO]; for (int i = 0; i < (int)[self.inputs count]; i++) { for (int j = 0; j < [self.inputs[i] count]; j++) { NSString *result = self.corrects[i][j]; XCTAssertTrue([result vv_isSwiftFunction] == [boolResult[i] boolValue], @"%@ should %@ be a swift function", result, [boolResult[i] boolValue] ? @"" : @"not"); } } } -(void) testIsSwiftEnum { NSArray *boolResult = @[@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@YES,@NO,@NO]; for (int i = 0; i < (int)[self.inputs count]; i++) { for (int j = 0; j < [self.inputs[i] count]; j++) { NSString *result = self.corrects[i][j]; XCTAssertTrue([result vv_isSwiftEnum] == [boolResult[i] boolValue], @"%@ should %@ be a swift enum", result, [boolResult[i] boolValue] ? @"" : @"not"); } } } -(void) testIsSwiftProperty { NSArray *boolResult = @[@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@YES,@NO]; for (int i = 0; i < (int)[self.inputs count]; i++) { for (int j = 0; j < [self.inputs[i] count]; j++) { NSString *result = self.corrects[i][j]; XCTAssertTrue([result vv_isSwiftProperty] == [boolResult[i] boolValue], @"%@ should %@ be a swift property", result, [boolResult[i] boolValue] ? @"" : @"not"); } } } -(void) testIsSwiftExtension { NSArray *boolResult = @[@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@NO,@YES]; for (int i = 0; i < (int)[self.inputs count]; i++) { for (int j = 0; j < [self.inputs[i] count]; j++) { NSString *result = self.corrects[i][j]; XCTAssertTrue([result vv_isSwiftExtension] == [boolResult[i] boolValue], @"%@ should %@ be a swift extension", result, [boolResult[i] boolValue] ? @"" : @"not"); } } } @end ================================================ FILE: VVDocumenterTests/VVDocumenterTests-Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 ================================================ FILE: VVDocumenterTests/VVDocumenterTests-Prefix.pch ================================================ // // Prefix header for all source files of the 'VVDocumenterTests' target in the 'VVDocumenterTests' project // #ifdef __OBJC__ #import #import "NSString+PDRegex.h" #endif #define __DEBUG__ 1 #ifdef __DEBUG__ #define VVLog(...) NSLog(__VA_ARGS__) #else #define VVLog(...) do{} while(0) #endif ================================================ FILE: VVDocumenterTests/VVDocumenterTests.m ================================================ // // VVDocumenterTests.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-19. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import "VVDocumenter.h" #import "NSString+VVSyntax.h" #import "VVTestHelper.h" #import "NSTextView+VVTextGetter.h" @interface VVDocumenterTests : XCTestCase @property NSDictionary *testCaseDic; @end @implementation VVDocumenterTests - (void)setUp { [super setUp]; // Put setup code here; it will be run once, before the first test case. NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"VVMethodTestsCode" ofType:@"plist"]; self.testCaseDic = [NSDictionary dictionaryWithContentsOfFile:path]; } - (void)tearDown { // Put teardown code here; it will be run once, after the last test case. self.testCaseDic = nil; [super tearDown]; } -(void) testDocument { [self.testCaseDic enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSArray *cases, BOOL *stop) { [cases enumerateObjectsUsingBlock:^(NSDictionary *testDic, NSUInteger idx, BOOL *stop) { NSString *source = testDic[@"source"]; NSString *uniform = testDic[@"uniform"]; NSString *result = testDic[@"result"]; XCTAssertNotNil(source, @"Test source code should exist."); XCTAssertNotNil(uniform, @"Test uniform code should exist."); XCTAssertNotNil(result, @"Test result code should exist."); XCTAssertEqualObjects([source vv_stringByConvertingToUniform], uniform, @"Source should be converted to uniform format corrctly."); XCTAssertTrue([VVTestHelper performSyntaxMethod:key onString:uniform], @"This uniform code should be %@",key); NSArray *otherTypeStrings = [VVTestHelper arrayOfExceptCodeType:key]; for (NSString *type in otherTypeStrings) { XCTAssertFalse([VVTestHelper performSyntaxMethod:type onString:uniform], @"This uniform code should not be %@",type); } VVDocumenter *documenter = nil; if ([key isEqualToString:@"vv_isSwiftEnum"]) { documenter = [[VVDocumenter alloc] initWithCode:source]; } else { documenter = [[VVDocumenter alloc] initWithCode:uniform]; } XCTAssertEqualObjects([documenter document], result, @"Result should be correct"); }]; }]; } @end ================================================ FILE: VVDocumenterTests/VVTestHelper.h ================================================ // // VVTestHelper.h // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-19. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import @interface VVTestHelper : NSObject +(NSArray *) testCodes; +(NSArray *) uniformCodes; +(NSArray *) arrayOfExceptCodeType:(NSString *)type; +(BOOL) performSyntaxMethod:(NSString *)selectorString onString:(NSString *)codestring; @end ================================================ FILE: VVDocumenterTests/VVTestHelper.m ================================================ // // VVTestHelper.m // VVDocumenter-Xcode // // Created by 王 巍 on 13-7-19. // // Copyright (c) 2015 Wei Wang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "VVTestHelper.h" @interface NSArray(vv_Removing) -(NSArray*)arrayByRemovingObject:(id)obj; @end @implementation NSArray (vv_Removing) -(NSArray*)arrayByRemovingObject:(id)obj { NSArray* newArray = [NSArray array]; NSUInteger indexOfObj = [self indexOfObject:obj]; newArray = [self subarrayWithRange:NSMakeRange(0, indexOfObj)]; newArray = [newArray arrayByAddingObjectsFromArray:[self subarrayWithRange:NSMakeRange(indexOfObj+1, self.count - indexOfObj-1)]]; return newArray; } @end static NSArray *_typeStrings; @implementation VVTestHelper +(NSArray *) testCodes { NSArray *methods = @[@"+ (ADTransition *)nullTransition;", @" - (BOOL) application: (UIApplication *) application \n didFinishLaunchingWithOptions: (NSDictionary *) launchOptions;", @"- (id)initWithDuration:(CFTimeInterval)duration sourceRect:(CGRect)sourceRect {", @"-(void)whenLinked:(void (^)(void))actionHandler;"]; NSArray *functions = @[@"void dosomething ( int x, int y );", @"int main(int argc, char *argv[]) \n {", @"void NoParamFunc();", @"typeof void(^IBLShareSuccessBlock)(ShareType type, SSPublishContentState state, id statusInfo, BOOL end);"]; NSArray *properties = @[@"@property (nonatomic, copy ) NSString *code;", @" @property ( nonatomic, strong ) Miao* test;", @"@property ( assign, strong ) int test;"]; NSArray *macros = @[@"#define MAX(A,B) ({", @"#define MIN(A,B) ((A) < (B) ? (A) : (B))", @"#define ABS(A) ((A) < 0 ? (-(A)) : (A))"]; NSArray *structs = @[@"struct Foo \n {", @" struct node {", @"struct objc_object {"]; NSArray *enums = @[@"typedef NS_ENUM {", @"typedef NS_ENUM \n {", @" typedef NS_ENUM{"]; NSArray *unions = @[@"union {", @" union \n {", @" union{"]; NSArray *others = @[@"options = options | NSRegularExpressionDotMatchesLineSeparators;", @"if (resultUntilSemiColon && resultUntilBrace) {", @"static dispatch_once_t once;"]; NSArray *compileKeywords = @[@"@interface VVDocumenter : NSObject \n {", @"@interface SyntaxTests()\n@property (nonatomic, retain) NSArray* inputs;", @"@implementation SyntaxTests\n\n- (void)setUp\n{", @"@interface A (a)\n- (id) foo;"]; NSArray *swiftFunctions = @[@"func sayHello(personName: String) -> String {", @"func halfOpenRangeLength(start: Int, end: Int) -> Int\n {", @"func sayHelloWorld() ->String", @"func testParamsType(var a: Int) {", @"init(style: Style, gearing: Gearing, handlebar: Handlebar, frameSize centimeters: Int) {", @"public subscript(key: KeyType)-> ValueType? {", @"func methodCouldThrows(count: Int) throws -> Int {", @"func methodCouldThrows() throws {", @"func methodCouldThrows(count: Int, name: String, f: (Int, String) throws -> Void) rethrows -> Int {"]; /* //Now there is no difference between Objective-C (C) struct and Swift struct. Ignore this. NSArray *swiftStructs = @[@"struct FixedLengthRange {", @"public struct SomeStructure \n {", @"public struct SomeStructure \n {",]; */ NSArray *swiftEnum = @[@"enum CompassPoint {", @"enum SomeEnumeration \n {", @"enum Planet { "]; NSArray *swiftProperties = @[@"let gearing : Gearing", @"var size = Size()", @"lazy var importer = DataImporter()", @"private ( set ) var distanceTravelled:Double"]; NSArray *swiftExtension = @[@"extension SomeViewController: UITableViewDelegate {", @"extension MyClass \n {", @"private extension PP : DelegateA, DelegateB {"]; return @[methods,functions,properties,macros,structs,enums,unions,others,compileKeywords,swiftFunctions,swiftEnum,swiftProperties, swiftExtension]; } +(NSArray *) uniformCodes { NSArray *methods = @[@"+(ADTransition *)nullTransition;", @" -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;", @"-(id)initWithDuration:(CFTimeInterval)duration sourceRect:(CGRect)sourceRect {", @"-(void)whenLinked:(void(^)(void))actionHandler;"]; NSArray *functions = @[@"void dosomething( int x, int y );", @"int main(int argc, char *argv[]){", @"void NoParamFunc();", @"typeof void(^IBLShareSuccessBlock)(ShareType type, SSPublishContentState state, id statusInfo, BOOL end);"]; NSArray *properties = @[@"@property(nonatomic, copy )NSString *code;", @" @property( nonatomic, strong )Miao* test;", @"@property( assign, strong )int test;"]; NSArray *macros = @[@"#define MAX(A,B)({", @"#define MIN(A,B)((A)<(B)?(A):(B))", @"#define ABS(A)((A)< 0 ?(-(A)):(A))"]; NSArray *structs = @[@"struct Foo {", @" struct node {", @"struct objc_object {"]; NSArray *enums = @[@"typedef NS_ENUM {", @"typedef NS_ENUM {", @" typedef NS_ENUM{"]; NSArray *unions = @[@"union {", @" union {", @" union{"]; NSArray *others = @[@"options = options | NSRegularExpressionDotMatchesLineSeparators;", @"if(resultUntilSemiColon && resultUntilBrace){", @"static dispatch_once_t once;"]; NSArray *compileKeywords = @[@"@interface VVDocumenter : NSObject {", @"@interface SyntaxTests()@property(nonatomic, retain)NSArray* inputs;", @"@implementation SyntaxTests -(void)setUp {", @"@interface A(a)-(id)foo;"]; NSArray *swiftFunctions = @[@"func sayHello(personName: String)-> String {", @"func halfOpenRangeLength(start: Int, end: Int)-> Int {", @"func sayHelloWorld()->String", @"func testParamsType(var a: Int){", @"init(style: Style, gearing: Gearing, handlebar: Handlebar, frameSize centimeters: Int){", @"public subscript(key: KeyType)-> ValueType? {", @"func methodCouldThrows(count: Int)throws -> Int {", @"func methodCouldThrows()throws {", @"func methodCouldThrows(count: Int, name: String, f:(Int, String)throws -> Void)rethrows -> Int {"]; /* //Now there is no difference between Objective-C (C) struct and Swift struct. Ignore this. NSArray *swiftStructs = @[@"struct FixedLengthRange {", @"public struct SomeStructure \n {", @"public struct SomeStructure \n {",]; */ NSArray *swiftEnum = @[@"enum CompassPoint {", @"enum SomeEnumeration {", @"enum Planet { "]; NSArray *swiftProperties = @[@"let gearing : Gearing", @"var size = Size()", @"lazy var importer = DataImporter()", @"private( set )var distanceTravelled:Double"]; NSArray *swiftExtension = @[@"extension SomeViewController: UITableViewDelegate {", @"extension MyClass {", @"private extension PP : DelegateA, DelegateB {"]; return @[methods,functions,properties,macros,structs,enums,unions,others,compileKeywords,swiftFunctions,swiftEnum,swiftProperties, swiftExtension]; } +(NSArray *) arrayOfExceptCodeType:(NSString *)type { if (!_typeStrings) { //Save all type specify method names in NSString+VVSyntax _typeStrings = @[@"vv_isObjCMethod", @"vv_isCFunction", @"vv_isProperty", @"vv_isMacro", @"vv_isStruct", @"vv_isEnum", @"vv_isUnion", @"vv_isComplieKeyword", @"vv_isSwiftFunction", @"vv_isSwiftEnum", @"vv_isSwiftProperty", @"vv_isSwiftExtension"]; } return [_typeStrings arrayByRemovingObject:type]; } +(BOOL) performSyntaxMethod:(NSString *)selectorString onString:(NSString *)codestring { SEL selector =NSSelectorFromString(selectorString); BOOL returnValue = NO; if ([codestring respondsToSelector:selector]) { NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: [[codestring class] instanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:codestring]; [invocation invoke]; [invocation getReturnValue:&returnValue]; } return returnValue; } @end ================================================ FILE: VVDocumenterTests/en.lproj/InfoPlist.strings ================================================ /* Localized versions of Info.plist keys */