0001    //
0002    //  Clang+SourceKitten.swift
0003    //  SourceKitten
0004    //
0005    //  Created by Thomas Goyne on 9/17/15.
0006    //  Copyright © 2015 SourceKitten. All rights reserved.
0007    //
0008    
0009    #if SWIFT_PACKAGE
0010    import Clang_C
0011    #endif
0012    import Foundation
0013    import SWXMLHash
0014    
0015    struct ClangIndex
ClangTranslationUnit.swift:61
        let clangIndex = ClangIndex()
{ 0016 private let cx
Clang+SourceKitten.swift:19
        return clang_createTranslationUnitFromSourceFile(cx,
= clang_createIndex(0, 1) 0017 0018 func open
ClangTranslationUnit.swift:62
        clangTranslationUnits = headerFiles.map { clangIndex.open(file: $0, args: cStringCompilerArguments) }
(file file: String, args: [UnsafePointer<Int8>]) -> CXTranslationUnit { 0019 return clang_createTranslationUnitFromSourceFile(cx, 0020 file, 0021 Int32(args.count), 0022 args, 0023 0, 0024 nil) 0025 } 0026 } 0027 0028 extension CXString: CustomStringConvertible { 0029 func str
Clang+SourceKitten.swift:34
        return str() ?? "<null>"
Clang+SourceKitten.swift:68
        let commentXML = clang_FullComment_getAsXML(comment).str() ?? ""
Clang+SourceKitten.swift:88
        let spelling = clang_getCursorSpelling(self).str()!
Clang+SourceKitten.swift:118
        return clang_getCursorUSR(self).str()
Clang+SourceKitten.swift:141
        let rawComment = clang_Cursor_getRawCommentText(self).str()
Clang+SourceKitten.swift:160
        return clang_ParamCommandComment_getParamName(self).str()
Clang+SourceKitten.swift:169
            return [.Verbatim(clang_VerbatimLineComment_getText(self).str()!)]
Clang+SourceKitten.swift:188
            if let text = clang_TextComment_getText(child).str() {
Clang+SourceKitten.swift:196
                ret += "@" + clang_InlineCommandComment_getCommandName(child).str()!
Clang+SourceKitten.swift:210
        return clang_BlockCommandComment_getCommandName(self).str()
SourceLocation.swift:32
        self.init(file: clang_getFileName(cxfile).str() ?? "<none>",
() -> String? { 0030 return String.fromCString(clang_getCString(self)) 0031 } 0032 0033 public var description: String { 0034 return str() ?? "<null>" 0035 } 0036 } 0037 0038 extension CXTranslationUnit { 0039 func cursor
ClangTranslationUnit.swift:64
            .flatMap { $0.cursor().flatMap(SourceDeclaration.init) }
() -> CXCursor { 0040 return clang_getTranslationUnitCursor(self) 0041 } 0042 } 0043 0044 extension CXCursor { 0045 func location
SourceDeclaration.swift:94
        location = cursor.location()
() -> SourceLocation { 0046 return SourceLocation(clangLocation: clang_getCursorLocation(self)) 0047 } 0048 0049 func extent
Clang+SourceKitten.swift:82
        let cursorExtent = extent()
SourceDeclaration.swift:95
        extent = cursor.extent()
() -> (start: SourceLocation, end: SourceLocation) { 0050 let extent = clang_getCursorExtent(self) 0051 let start = SourceLocation(clangLocation: clang_getRangeStart(extent)) 0052 let end = SourceLocation(clangLocation: clang_getRangeEnd(extent)) 0053 return (start, end) 0054 } 0055 0056 func shouldDocument
SourceDeclaration.swift:90
        guard cursor.shouldDocument() else {
() -> Bool { 0057 return clang_isDeclaration(kind) != 0 && 0058 kind != CXCursor_ParmDecl && 0059 kind != CXCursor_TemplateTypeParameter && 0060 clang_Location_isInSystemHeader(clang_getCursorLocation(self)) == 0 0061 } 0062 0063 func declaration
SourceDeclaration.swift:98
        declaration = cursor.declaration()
() -> String? { 0064 let comment = parsedComment() 0065 if comment.kind() == CXComment_Null { 0066 return str() 0067 } 0068 let commentXML = clang_FullComment_getAsXML(comment).str() ?? "" 0069 guard let rootXML = SWXMLHash.parse(commentXML).children.first else { 0070 fatalError("couldn't parse XML") 0071 } 0072 return rootXML["Declaration"].element?.text? 0073 .stringByReplacingOccurrencesOfString("\n@end", withString: "") 0074 .stringByReplacingOccurrencesOfString("@property(", withString: "@property (") 0075 } 0076 0077 func objCKind
Clang+SourceKitten.swift:89
        let type = objCKind()
SourceDeclaration.swift:93
        type = cursor.objCKind()
() -> ObjCDeclarationKind { 0078 return ObjCDeclarationKind.fromClang(kind) 0079 } 0080 0081 func str
Clang+SourceKitten.swift:66
            return str()
() -> String? { 0082 let cursorExtent = extent() 0083 let contents = try! NSString(contentsOfFile: cursorExtent.start.file, encoding: NSUTF8StringEncoding) 0084 return contents.substringWithSourceRange(cursorExtent.start, end: cursorExtent.end) 0085 } 0086 0087 func name
SourceDeclaration.swift:96
        name = cursor.name()
() -> String { 0088 let spelling = clang_getCursorSpelling(self).str()! 0089 let type = objCKind() 0090 if let usrString = usr() where spelling.isEmpty && type == .Enum { 0091 // libClang considers enums declared like `typedef enum {} name;` rather than `NS_ENUM()` 0092 // to have a cursor spelling of "" (empty string). So we parse the USR to extract the actual name. 0093 let prefix = "c:@EA@" 0094 assert(usrString.hasPrefix(prefix)) 0095 let index = usrString.startIndex.advancedBy(prefix.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)) 0096 return usrString.substringFromIndex(index) 0097 } else if let usrNSString = usr() as NSString? where type == .Category { 0098 let ext = (usrNSString.rangeOfString("c:objc(ext)").location == 0) 0099 let regex = try! NSRegularExpression(pattern: "(\\w+)@(\\w+)", options: []) 0100 let range = NSRange(location: 0, length: usrNSString.length) 0101 let matches = regex.matchesInString(usrNSString as String, options: [], range: range) 0102 if matches.count > 0 { 0103 let categoryOn = usrNSString.substringWithRange(matches[0].rangeAtIndex(1)) 0104 let categoryName = ext ? "" : usrNSString.substringWithRange(matches[0].rangeAtIndex(2)) 0105 return "\(categoryOn)(\(categoryName))" 0106 } else { 0107 fatalError("Couldn't get category name") 0108 } 0109 } else if type == .MethodInstance { 0110 return "-" + spelling 0111 } else if type == .MethodClass { 0112 return "+" + spelling 0113 } 0114 return spelling 0115 } 0116 0117 func usr
Clang+SourceKitten.swift:90
        if let usrString = usr() where spelling.isEmpty && type == .Enum {
Clang+SourceKitten.swift:97
        } else if let usrNSString = usr() as NSString? where type == .Category {
SourceDeclaration.swift:97
        usr = cursor.usr()
() -> String? { 0118 return clang_getCursorUSR(self).str() 0119 } 0120 0121 func visit
Clang+SourceKitten.swift:131
        visit() { cursor, _ in
(block: CXCursorVisitorBlock) { 0122 clang_visitChildrenWithBlock(self, block) 0123 } 0124 0125 func parsedComment
Clang+SourceKitten.swift:64
        let comment = parsedComment()
SourceDeclaration.swift:99
        documentation = Documentation(comment: cursor.parsedComment())
() -> CXComment { 0126 return clang_Cursor_getParsedComment(self) 0127 } 0128 0129 func flatMap
ClangTranslationUnit.swift:64
            .flatMap { $0.cursor().flatMap(SourceDeclaration.init) }
SourceDeclaration.swift:101
        children = cursor.flatMap(SourceDeclaration.init).rejectPropertyMethods()
<T>(block: (CXCursor) -> T?) -> [T] { 0130 var ret = [T]() 0131 visit() { cursor, _ in 0132 if let val = block(cursor) { 0133 ret.append(val) 0134 } 0135 return CXChildVisit_Continue 0136 } 0137 return ret 0138 } 0139 0140 func commentBody
SourceDeclaration.swift:100
        commentBody = cursor.commentBody()
() -> String? { 0141 let rawComment = clang_Cursor_getRawCommentText(self).str() 0142 let replacements = [ 0143 "@param ": "- parameter: ", 0144 "@return ": "- returns: ", 0145 "@warning ": "- warning: ", 0146 "@see ": "- see: ", 0147 "@note ": "- note: ", 0148 ] 0149 var commentBody = rawComment?.commentBody() 0150 for (original, replacement) in replacements { 0151 commentBody = commentBody?.stringByReplacingOccurrencesOfString(original, withString: replacement) 0152 } 0153 return commentBody 0154 } 0155 } 0156 0157 extension CXComment { 0158 func paramName
Parameter.swift:18
        name = comment.paramName() ?? "<none>"
() -> String? { 0159 guard clang_Comment_getKind(self) == CXComment_ParamCommand else { return nil } 0160 return clang_ParamCommandComment_getParamName(self).str() 0161 } 0162 0163 func paragraph
Parameter.swift:19
        discussion = comment.paragraph().paragraphToString()
() -> CXComment { 0164 return clang_BlockCommandComment_getParagraph(self) 0165 } 0166 0167 func paragraphToString
Clang+SourceKitten.swift:175
                ret += child.paragraphToString()
Documentation.swift:25
            $0.paragraphToString()
Parameter.swift:19
        discussion = comment.paragraph().paragraphToString()
(kindString: String? = nil) -> [Text] { 0168 if kind() == CXComment_VerbatimLine { 0169 return [.Verbatim(clang_VerbatimLineComment_getText(self).str()!)] 0170 } 0171 if kind() == CXComment_BlockCommand { 0172 var ret = [Text]() 0173 for i in 0..<clang_Comment_getNumChildren(self) { 0174 let child = clang_Comment_getChild(self, i) 0175 ret += child.paragraphToString() 0176 } 0177 return ret 0178 } 0179 0180 guard kind() == CXComment_Paragraph else { 0181 print("not a paragraph: \(kind())") 0182 return [] 0183 } 0184 0185 var ret = "" 0186 for i in 0..<clang_Comment_getNumChildren(self) { 0187 let child = clang_Comment_getChild(self, i) 0188 if let text = clang_TextComment_getText(child).str() { 0189 if ret != "" { 0190 ret += "\n" 0191 } 0192 ret += text 0193 } 0194 else if child.kind() == CXComment_InlineCommand { 0195 // @autoreleasepool etc. get parsed as commands when not in code blocks 0196 ret += "@" + clang_InlineCommandComment_getCommandName(child).str()! 0197 } 0198 else { 0199 print("not text: \(child.kind())") 0200 } 0201 } 0202 return [.Para(ret.stringByRemovingCommonLeadingWhitespaceFromLines(), kindString)] 0203 } 0204 0205 func kind
Clang+SourceKitten.swift:65
        if comment.kind() == CXComment_Null {
Clang+SourceKitten.swift:168
        if kind() == CXComment_VerbatimLine {
Clang+SourceKitten.swift:171
        if kind() == CXComment_BlockCommand  {
Clang+SourceKitten.swift:180
        guard kind() == CXComment_Paragraph else {
Clang+SourceKitten.swift:181
            print("not a paragraph: \(kind())")
Clang+SourceKitten.swift:194
            else if child.kind() == CXComment_InlineCommand {
Clang+SourceKitten.swift:199
                print("not text: \(child.kind())")
Documentation.swift:20
            $0.kind() == CXComment_ParamCommand
Documentation.swift:23
            $0.kind() == CXComment_BlockCommand && $0.commandName() == "return"
() -> CXCommentKind { 0206 return clang_Comment_getKind(self) 0207 } 0208 0209 func commandName
Documentation.swift:23
            $0.kind() == CXComment_BlockCommand && $0.commandName() == "return"
() -> String? { 0210 return clang_BlockCommandComment_getCommandName(self).str() 0211 } 0212 0213 func count
Documentation.swift:18
        let comments = (0..<comment.count()).map { comment[$0] }
() -> UInt32 { 0214 return clang_Comment_getNumChildren(self) 0215 } 0216 0217 subscript
Documentation.swift:18
        let comments = (0..<comment.count()).map { comment[$0] }
(idx: UInt32) -> CXComment { 0218 return clang_Comment_getChild(self, idx) 0219 } 0220 } 0221