diff --git a/.swiftlint.yml b/.swiftlint.yml index f951bfd25..a74cd7894 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -7,6 +7,7 @@ excluded: - Source/SourceKittenFramework/library_wrapper_Documentation.swift - Source/SourceKittenFramework/library_wrapper_Index.swift - Source/SourceKittenFramework/library_wrapper_sourcekitd.swift + - Source/SourceKittenFramework/UIDNamespace+generated.swift opt_in_rules: - attributes - closure_end_indentation diff --git a/CHANGELOG.md b/CHANGELOG.md index b2837f78f..41b3da845 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -134,6 +134,12 @@ [JP Simard](https://github.com/jpsim) [Norio Nomura](https://github.com/norio-nomura) +* Some APIs changed to `throws`. + * `File.format(trimmingTrailingWhitespace:useTabs:indentWidth:) throws` + * `Structure.init(file:) throws` + * `SyntaxMap.init(file:) throws` + [Norio Nomura](https://github.com/norio-nomura) + ##### Enhancements * Add `--spm-module [ModuleName]` flag to `complete` to automatically detect diff --git a/Source/SourceKittenFramework/Clang+SourceKitten.swift b/Source/SourceKittenFramework/Clang+SourceKitten.swift index 386df9e93..b8e30a05b 100644 --- a/Source/SourceKittenFramework/Clang+SourceKitten.swift +++ b/Source/SourceKittenFramework/Clang+SourceKitten.swift @@ -200,17 +200,20 @@ extension CXCursor { swiftUUID = NSUUID().uuidString setUUIDString(uidString: swiftUUID, for: file) // Generate Swift interface, associating it with the UUID - _ = Request.interface(file: file, uuid: swiftUUID).send() + guard let _ = try? Request.interface(file: file, uuid: swiftUUID).failableSend() else { + return nil + } } guard let usr = usr(), - let usrOffset = Request.findUSR(file: swiftUUID, usr: usr).send()[SwiftDocKey.offset.rawValue] as? Int64 else { + let findUSR = try? Request.findUSR(file: swiftUUID, usr: usr).failableSend(), + let usrOffset = findUSR.offset else { return nil } - let cursorInfo = Request.cursorInfo(file: swiftUUID, offset: usrOffset, arguments: compilerArguments).send() - guard let docsXML = cursorInfo[SwiftDocKey.fullXMLDocs.rawValue] as? String, - let swiftDeclaration = SWXMLHash.parse(docsXML).children.first?["Declaration"].element?.text else { + guard let cursorInfo = try? Request.cursorInfo(file: swiftUUID, offset: usrOffset, arguments: compilerArguments).failableSend(), + let docsXML = cursorInfo.docFullAsXML, + let swiftDeclaration = SWXMLHash.parse(docsXML).children.first?["Declaration"].element?.text else { return nil } return swiftDeclaration diff --git a/Source/SourceKittenFramework/CodeCompletionItem.swift b/Source/SourceKittenFramework/CodeCompletionItem.swift index e7d79c1a7..d0a09e39c 100644 --- a/Source/SourceKittenFramework/CodeCompletionItem.swift +++ b/Source/SourceKittenFramework/CodeCompletionItem.swift @@ -17,12 +17,6 @@ fileprivate extension Dictionary { } public struct CodeCompletionItem: CustomStringConvertible { - #if os(Linux) - public typealias NumBytesInt = Int - #else - public typealias NumBytesInt = Int64 - #endif - public let kind: String public let context: String public let name: String? @@ -32,7 +26,7 @@ public struct CodeCompletionItem: CustomStringConvertible { public let moduleName: String? public let docBrief: String? public let associatedUSRs: String? - public let numBytesToErase: NumBytesInt? + public let numBytesToErase: Int? /// Dictionary representation of CodeCompletionItem. Useful for NSJSONSerialization. public var dictionaryValue: [String: Any] { @@ -49,30 +43,29 @@ public struct CodeCompletionItem: CustomStringConvertible { } public var description: String { - return toJSON(dictionaryValue.bridge()) + return toJSON(dictionaryValue) } - public static func parse(response: [String: SourceKitRepresentable]) -> [CodeCompletionItem] { - return (response["key.results"] as! [SourceKitRepresentable]).map { item in - let dict = item as! [String: SourceKitRepresentable] - return CodeCompletionItem(kind: dict["key.kind"] as! String, - context: dict["key.context"] as! String, - name: dict["key.name"] as? String, - descriptionKey: dict["key.description"] as? String, - sourcetext: dict["key.sourcetext"] as? String, - typeName: dict["key.typename"] as? String, - moduleName: dict["key.modulename"] as? String, - docBrief: dict["key.doc.brief"] as? String, - associatedUSRs: dict["key.associated_usrs"] as? String, - numBytesToErase: dict["key.num_bytes_to_erase"] as? NumBytesInt) - } + public static func parse(response: SourceKitVariant) -> [CodeCompletionItem] { + return response.results?.map { dict in + return CodeCompletionItem(kind: dict.kind?.description ?? "", + context: dict.context!, + name: dict.name, + descriptionKey: dict.description, + sourcetext: dict.sourceText, + typeName: dict.typeName, + moduleName: dict.moduleName, + docBrief: dict.docBrief, + associatedUSRs: dict.associatedUsrs, + numBytesToErase: dict["key.num_bytes_to_erase"]?.int) + } ?? [] } } // MARK: - migration support extension CodeCompletionItem { @available(*, unavailable, renamed: "parse(response:)") - public static func parseResponse(_ response: [String: SourceKitRepresentable]) -> [CodeCompletionItem] { + public static func parseResponse(_ response: [String: Any]) -> [CodeCompletionItem] { fatalError() } } diff --git a/Source/SourceKittenFramework/File.swift b/Source/SourceKittenFramework/File.swift index 44d206c97..c7d9b7873 100644 --- a/Source/SourceKittenFramework/File.swift +++ b/Source/SourceKittenFramework/File.swift @@ -51,32 +51,37 @@ public final class File { lines = contents.bridge().lines() } - /** - Formats the file. - */ + /// Formats the file. + /// + /// - Parameters: + /// - trimmingTrailingWhitespace: Boolean + /// - useTabs: Boolean + /// - indentWidth: Int + /// - Returns: formatted String + /// - Throws: Request.Error public func format(trimmingTrailingWhitespace: Bool, useTabs: Bool, - indentWidth: Int) -> String { + indentWidth: Int) throws -> String { guard let path = path else { return contents } - _ = Request.editorOpen(file: self).send() + _ = try Request.editorOpen(file: self).failableSend() var newContents = [String]() var offset = 0 for line in lines { - let formatResponse = Request.format(file: path, - line: Int64(line.index), + let formatResponse = try Request.format(file: path, + line: line.index, useTabs: useTabs, - indentWidth: Int64(indentWidth)).send() - let newText = formatResponse["key.sourcetext"] as! String + indentWidth: indentWidth).failableSend() + let newText = formatResponse.sourceText! newContents.append(newText) guard newText != line.content else { continue } - _ = Request.replaceText(file: path, - offset: Int64(line.byteRange.location + offset), - length: Int64(line.byteRange.length - 1), - sourceText: newText).send() + _ = try Request.replaceText(file: path, + offset: line.byteRange.location + offset, + length: line.byteRange.length - 1, + sourceText: newText).failableSend() let oldLength = line.byteRange.length let newLength = newText.lengthOfBytes(using: .utf8) offset += 1 + newLength - oldLength @@ -98,13 +103,13 @@ public final class File { - returns: Source declaration if successfully parsed. */ - public func parseDeclaration(_ dictionary: [String: SourceKitRepresentable]) -> String? { + public func parseDeclaration(_ dictionary: SourceKitVariant) -> String? { guard shouldParseDeclaration(dictionary), - let start = SwiftDocKey.getOffset(dictionary).map({ Int($0) }) else { + let start = dictionary.offset else { return nil } let substring: String? - if let end = SwiftDocKey.getBodyOffset(dictionary) { + if let end = dictionary.bodyOffset { substring = contents.bridge().substringStartingLinesWithByteRange(start: start, length: Int(end) - start) } else { substring = contents.bridge().substringLinesWithByteRange(start: start, length: 0) @@ -119,15 +124,14 @@ public final class File { - returns: Line numbers containing the declaration's implementation. */ - public func parseScopeRange(_ dictionary: [String: SourceKitRepresentable]) -> (start: Int, end: Int)? { + public func parseScopeRange(_ dictionary: SourceKitVariant) -> (start: Int, end: Int)? { if !shouldParseDeclaration(dictionary) { return nil } - return SwiftDocKey.getOffset(dictionary).flatMap { start in - let start = Int(start) - let end = SwiftDocKey.getBodyOffset(dictionary).flatMap { bodyOffset in - return SwiftDocKey.getBodyLength(dictionary).map { bodyLength in - return Int(bodyOffset + bodyLength) + return dictionary.offset.flatMap { start in + let end = dictionary.bodyOffset.flatMap { bodyOffset in + dictionary.bodyLength.map { bodyLength in + bodyOffset + bodyLength } } ?? start let length = end - start @@ -142,13 +146,15 @@ public final class File { - returns: Mark name if successfully parsed. */ - private func parseMarkName(_ dictionary: [String: SourceKitRepresentable]) -> String? { - precondition(SwiftDocKey.getKind(dictionary)! == SyntaxKind.commentMark.rawValue) - let offset = Int(SwiftDocKey.getOffset(dictionary)!) - let length = Int(SwiftDocKey.getLength(dictionary)!) - let fileContentsData = contents.data(using: .utf8) - let subdata = fileContentsData?.subdata(in: Range(offset..<(offset + length))) - return subdata.flatMap { String(data: $0, encoding: .utf8) } + private func parseMarkName(_ dictionary: SourceKitVariant) -> String? { + precondition(dictionary.kind == UID.SourceLangSwiftSyntaxtype.commentMark) + guard let offset = dictionary.offset, + let length = dictionary.length, + let fileContentsData = contents.data(using: .utf8) else { + return nil + } + let subdata = fileContentsData.subdata(in: Range(offset..<(offset + length))) + return String(data: subdata, encoding: .utf8) } /** @@ -158,40 +164,39 @@ public final class File { - parameter dictionary: Dictionary to process. - parameter cursorInfoRequest: Cursor.Info request to get declaration information. */ - public func process(dictionary: [String: SourceKitRepresentable], cursorInfoRequest: sourcekitd_object_t? = nil, - syntaxMap: SyntaxMap? = nil) -> [String: SourceKitRepresentable] { + public func process(dictionary: SourceKitVariant, cursorInfoRequest: SourceKitObject? = nil, + syntaxMap: SyntaxMap? = nil) -> SourceKitVariant { var dictionary = dictionary if let cursorInfoRequest = cursorInfoRequest { - dictionary = merge( - dictionary, + dictionary = dictionary.merging(with: dictWithCommentMarkNamesCursorInfo(dictionary, cursorInfoRequest: cursorInfoRequest) ) } // Parse declaration and add to dictionary if let parsedDeclaration = parseDeclaration(dictionary) { - dictionary[SwiftDocKey.parsedDeclaration.rawValue] = parsedDeclaration + dictionary.parsedDeclaration = parsedDeclaration } // Parse scope range and add to dictionary if let parsedScopeRange = parseScopeRange(dictionary) { - dictionary[SwiftDocKey.parsedScopeStart.rawValue] = Int64(parsedScopeRange.start) - dictionary[SwiftDocKey.parsedScopeEnd.rawValue] = Int64(parsedScopeRange.end) + dictionary.parsedScopeStart = parsedScopeRange.start + dictionary.parsedScopeEnd = parsedScopeRange.end } // Parse `key.doc.full_as_xml` and add to dictionary - if let parsedXMLDocs = (SwiftDocKey.getFullXMLDocs(dictionary).flatMap(parseFullXMLDocs)) { - dictionary = merge(dictionary, parsedXMLDocs) + if let parsedXMLDocs = dictionary.docFullAsXML.flatMap(parseFullXMLDocs) { + dictionary = dictionary.merging(with: parsedXMLDocs) } if let commentBody = (syntaxMap.flatMap { parseDocumentationCommentBody(dictionary, syntaxMap: $0) }) { // Parse documentation comment and add to dictionary - dictionary[SwiftDocKey.documentationComment.rawValue] = commentBody + dictionary.documentationComment = commentBody } // Update substructure if let substructure = newSubstructure(dictionary, cursorInfoRequest: cursorInfoRequest, syntaxMap: syntaxMap) { - dictionary[SwiftDocKey.substructure.rawValue] = substructure + dictionary.subStructure = substructure } return dictionary } @@ -204,18 +209,17 @@ public final class File { - parameter documentedTokenOffsets: Offsets that are likely documented. - parameter cursorInfoRequest: Cursor.Info request to get declaration information. */ - internal func furtherProcess(dictionary: [String: SourceKitRepresentable], documentedTokenOffsets: [Int], - cursorInfoRequest: sourcekitd_object_t, - syntaxMap: SyntaxMap) -> [String: SourceKitRepresentable] { + internal func furtherProcess(dictionary: SourceKitVariant, documentedTokenOffsets: [Int], + cursorInfoRequest: SourceKitObject, syntaxMap: SyntaxMap) -> SourceKitVariant { var dictionary = dictionary let offsetMap = makeOffsetMap(documentedTokenOffsets: documentedTokenOffsets, dictionary: dictionary) for offset in offsetMap.keys.reversed() { // Do this in reverse to insert the doc at the correct offset - if let rawResponse = Request.send(cursorInfoRequest: cursorInfoRequest, atOffset: Int64(offset)), - case let response = process(dictionary: rawResponse, cursorInfoRequest: nil, syntaxMap: syntaxMap), - let kind = SwiftDocKey.getKind(response), - SwiftDeclarationKind(rawValue: kind) != nil, - let parentOffset = offsetMap[offset].flatMap({ Int64($0) }), - let inserted = insert(doc: response, parent: dictionary, offset: parentOffset) { + if let response = Request.send(cursorInfoRequest: cursorInfoRequest, atOffset: offset) + .map({ process(dictionary: $0, cursorInfoRequest: nil, syntaxMap: syntaxMap) }), + let kind = response.kind, + kind.isMemberOfSourceLangSwiftDecl, + let parentOffset = offsetMap[offset], + let inserted = insert(doc: response, parent: dictionary, offset: parentOffset) { dictionary = inserted } } @@ -233,10 +237,9 @@ public final class File { `processDictionary(_:cursorInfoRequest:syntaxMap:)` on its elements, only keeping comment marks and declarations. */ - private func newSubstructure(_ dictionary: [String: SourceKitRepresentable], cursorInfoRequest: sourcekitd_object_t?, - syntaxMap: SyntaxMap?) -> [SourceKitRepresentable]? { - return SwiftDocKey.getSubstructure(dictionary)? - .map({ $0 as! [String: SourceKitRepresentable] }) + private func newSubstructure(_ dictionary: SourceKitVariant, cursorInfoRequest: SourceKitObject?, + syntaxMap: SyntaxMap?) -> [SourceKitVariant]? { + return dictionary.subStructure? .filter(isDeclarationOrCommentMark) .map { process(dictionary: $0, cursorInfoRequest: cursorInfoRequest, syntaxMap: syntaxMap) @@ -249,29 +252,29 @@ public final class File { - parameter dictionary: Dictionary to update. - parameter cursorInfoRequest: Cursor.Info request to get declaration information. */ - private func dictWithCommentMarkNamesCursorInfo(_ dictionary: [String: SourceKitRepresentable], - cursorInfoRequest: sourcekitd_object_t) -> [String: SourceKitRepresentable]? { - guard let kind = SwiftDocKey.getKind(dictionary) else { + private func dictWithCommentMarkNamesCursorInfo(_ sourceKitVariant: SourceKitVariant, + cursorInfoRequest: SourceKitObject) -> SourceKitVariant? { + guard let kind = sourceKitVariant.kind else { return nil } // Only update dictionaries with a 'kind' key - if kind == SyntaxKind.commentMark.rawValue, let markName = parseMarkName(dictionary) { + if kind == UID.SourceLangSwiftSyntaxtype.commentMark, let markName = parseMarkName(sourceKitVariant) { // Update comment marks - return [SwiftDocKey.name.rawValue: markName] - } else if let decl = SwiftDeclarationKind(rawValue: kind), decl != .varParameter { + return [UID.Key.name.uid: SourceKitVariant(markName)] + } else if kind != UID.SourceLangSwiftDecl.varParameter { // Update if kind is a declaration (but not a parameter) var updateDict = Request.send(cursorInfoRequest: cursorInfoRequest, - atOffset: SwiftDocKey.getNameOffset(dictionary)!) ?? [:] + atOffset: sourceKitVariant.nameOffset!) ?? [:] // Skip kinds, since values from editor.open are more accurate than cursorinfo - updateDict.removeValue(forKey: SwiftDocKey.kind.rawValue) + updateDict.removeValue(forKey: .kind) // Skip offset and length. // Their values are same with "key.nameoffset" and "key.namelength" in most case. // When kind is extension, their values locate **the type's declaration** in their declared file. // That may be different from the file declaring extension. - updateDict.removeValue(forKey: SwiftDocKey.offset.rawValue) - updateDict.removeValue(forKey: SwiftDocKey.length.rawValue) + updateDict.removeValue(forKey: .offset) + updateDict.removeValue(forKey: .length) return updateDict } return nil @@ -285,10 +288,10 @@ public final class File { - returns: True if a doc should be inserted in the parent at the provided offset. */ - private func shouldInsert(parent: [String: SourceKitRepresentable], offset: Int64) -> Bool { - return SwiftDocKey.getSubstructure(parent) != nil && + private func shouldInsert(parent: SourceKitVariant, offset: Int) -> Bool { + return parent.subStructure != nil && ((offset == 0) || - (shouldTreatAsSameFile(parent) && SwiftDocKey.getNameOffset(parent) == offset)) + (shouldTreatAsSameFile(parent) && parent.nameOffset == offset)) } /** @@ -302,28 +305,27 @@ public final class File { - returns: Parent with doc inserted if successful. */ - private func insert(doc: [String: SourceKitRepresentable], parent: [String: SourceKitRepresentable], offset: Int64) -> [String: SourceKitRepresentable]? { + private func insert(doc: SourceKitVariant, parent: SourceKitVariant, offset: Int) -> SourceKitVariant? { var parent = parent if shouldInsert(parent: parent, offset: offset) { - var substructure = SwiftDocKey.getSubstructure(parent)! + var substructure = parent.subStructure! var insertIndex = substructure.count for (index, structure) in substructure.reversed().enumerated() { - if SwiftDocKey.getOffset(structure as! [String: SourceKitRepresentable])! < offset { + if structure.offset! < offset { break } insertIndex = substructure.count - index } substructure.insert(doc, at: insertIndex) - parent[SwiftDocKey.substructure.rawValue] = substructure + parent.subStructure = substructure return parent } - for key in parent.keys { - if let subArray = parent[key] as? [SourceKitRepresentable] { - var subArray = subArray + for (key, value) in parent.dictionary! { + if var subArray = value.array { for i in 0.. Bool { - return path == SwiftDocKey.getFilePath(dictionary) + internal func shouldTreatAsSameFile(_ sourceKitVariant: SourceKitVariant) -> Bool { + return path == sourceKitVariant.filePath } /** @@ -347,13 +349,13 @@ public final class File { - parameter dictionary: Dictionary to parse. */ - private func shouldParseDeclaration(_ dictionary: [String: SourceKitRepresentable]) -> Bool { + private func shouldParseDeclaration(_ sourceKitVariant: SourceKitVariant) -> Bool { // swiftlint:disable operator_usage_whitespace - let sameFile = shouldTreatAsSameFile(dictionary) - let hasTypeName = SwiftDocKey.getTypeName(dictionary) != nil - let hasAnnotatedDeclaration = SwiftDocKey.getAnnotatedDeclaration(dictionary) != nil - let hasOffset = SwiftDocKey.getOffset(dictionary) != nil - let isntExtension = SwiftDocKey.getKind(dictionary) != SwiftDeclarationKind.extension.rawValue + let sameFile = shouldTreatAsSameFile(sourceKitVariant) + let hasTypeName = sourceKitVariant.typeName != nil + let hasAnnotatedDeclaration = sourceKitVariant.annotatedDeclaration != nil + let hasOffset = sourceKitVariant.offset != nil + let isntExtension = sourceKitVariant.kind != UID.SourceLangSwiftDecl.extension // swiftlint:enable operator_usage_whitespace return sameFile && hasTypeName && hasAnnotatedDeclaration && hasOffset && isntExtension } @@ -367,22 +369,19 @@ public final class File { - returns: `dictionary`'s documentation comment body as a string, without any documentation syntax (`/** ... */` or `/// ...`). */ - public func parseDocumentationCommentBody(_ dictionary: [String: SourceKitRepresentable], syntaxMap: SyntaxMap) -> String? { - let isExtension = SwiftDocKey.getKind(dictionary).flatMap(SwiftDeclarationKind.init) == .extension - let hasFullXMLDocs = dictionary.keys.contains(SwiftDocKey.fullXMLDocs.rawValue) - let hasRawDocComment: Bool = { - if !dictionary.keys.contains("key.attributes") { return false } - let attributes = (dictionary["key.attributes"] as! [SourceKitRepresentable]) - .flatMap({ ($0 as! [String: SourceKitRepresentable]).values }) - .map({ $0 as! String }) - return attributes.contains("source.decl.attribute.__raw_doc_comment") - }() + public func parseDocumentationCommentBody(_ variant: SourceKitVariant, syntaxMap: SyntaxMap) -> String? { + let isExtension = variant.kind == UID.SourceLangSwiftDecl.extension + let hasFullXMLDocs = variant.docFullAsXML != nil + let hasRawDocComment = variant + .attributes? + .flatMap({ $0.attribute?.description }) + .contains("source.decl.attribute.__raw_doc_comment") ?? false let hasDocumentationComment = (hasFullXMLDocs && !isExtension) || hasRawDocComment guard hasDocumentationComment else { return nil } - if let offset = isExtension ? SwiftDocKey.getNameOffset(dictionary) : SwiftDocKey.getOffset(dictionary), - let commentByteRange = syntaxMap.commentRange(beforeOffset: Int(offset)), + if let offset = isExtension ? variant.nameOffset : variant.offset, + let commentByteRange = syntaxMap.commentRange(beforeOffset: offset), case let start = commentByteRange.lowerBound, case let end = commentByteRange.upperBound, let nsRange = contents.bridge().byteRangeToNSRange(start: start, length: end - start) { @@ -397,10 +396,10 @@ Returns true if the dictionary represents a source declaration or a mark-style c - parameter dictionary: Dictionary to parse. */ -private func isDeclarationOrCommentMark(_ dictionary: [String: SourceKitRepresentable]) -> Bool { - if let kind = SwiftDocKey.getKind(dictionary) { - return kind != SwiftDeclarationKind.varParameter.rawValue && - (kind == SyntaxKind.commentMark.rawValue || SwiftDeclarationKind(rawValue: kind) != nil) +private func isDeclarationOrCommentMark(_ dictionary: SourceKitVariant) -> Bool { + if let kind = dictionary.kind { + return kind != UID.SourceLangSwiftDecl.varParameter && + (kind == UID.SourceLangSwiftSyntaxtype.commentMark || kind.isMemberOfSourceLangSwiftDecl) } return false } @@ -410,68 +409,64 @@ Parse XML from `key.doc.full_as_xml` from `cursor.info` request. - parameter xmlDocs: Contents of `key.doc.full_as_xml` from SourceKit. -- returns: XML parsed as an `[String: SourceKitRepresentable]`. +- returns: XML parsed as an `SourceKitVariant`. */ -public func parseFullXMLDocs(_ xmlDocs: String) -> [String: SourceKitRepresentable]? { +public func parseFullXMLDocs(_ xmlDocs: String) -> SourceKitVariant? { let cleanXMLDocs = xmlDocs.replacingOccurrences(of: "", with: "") .replacingOccurrences(of: "", with: "") .replacingOccurrences(of: "", with: "`") .replacingOccurrences(of: "", with: "`") return SWXMLHash.parse(cleanXMLDocs).children.first.map { rootXML in - var docs = [String: SourceKitRepresentable]() - docs[SwiftDocKey.docType.rawValue] = rootXML.element?.name - docs[SwiftDocKey.docFile.rawValue] = rootXML.element?.allAttributes["file"]?.text - docs[SwiftDocKey.docLine.rawValue] = (rootXML.element?.allAttributes["line"]?.text).flatMap { - Int64($0) - } - docs[SwiftDocKey.docColumn.rawValue] = (rootXML.element?.allAttributes["column"]?.text).flatMap { - Int64($0) - } - docs[SwiftDocKey.docName.rawValue] = rootXML["Name"].element?.text - docs[SwiftDocKey.usr.rawValue] = rootXML["USR"].element?.text - docs[SwiftDocKey.docDeclaration.rawValue] = rootXML["Declaration"].element?.text + var docs: SourceKitVariant = [:] + docs.docType = rootXML.element?.name + docs.docFile = rootXML.element?.allAttributes["file"]?.text + docs.docLine = (rootXML.element?.allAttributes["line"]?.text).flatMap { Int($0) } + docs.docColumn = (rootXML.element?.allAttributes["column"]?.text).flatMap { Int($0) } + docs.docName = rootXML["Name"].element?.text + docs.usr = rootXML["USR"].element?.text + docs.docDeclaration = rootXML["Declaration"].element?.text let parameters = rootXML["Parameters"].children if !parameters.isEmpty { - func docParameters(from indexer: XMLIndexer) -> [String:SourceKitRepresentable] { + func docParameters(from indexer: XMLIndexer) -> SourceKitVariant { return [ - "name": (indexer["Name"].element?.text ?? ""), - "discussion": (indexer["Discussion"].childrenAsArray() ?? []) + "name": SourceKitVariant(indexer["Name"].element?.text ?? ""), + "discussion": SourceKitVariant(indexer["Discussion"].childrenAsArray() ?? []) ] } - docs[SwiftDocKey.docParameters.rawValue] = parameters.map(docParameters(from:)) as [SourceKitRepresentable] + docs.docParameters = parameters.map(docParameters(from:)) } - docs[SwiftDocKey.docDiscussion.rawValue] = rootXML["Discussion"].childrenAsArray() - docs[SwiftDocKey.docResultDiscussion.rawValue] = rootXML["ResultDiscussion"].childrenAsArray() + docs.docDiscussion = rootXML["Discussion"].childrenAsArray() + docs.docResultDiscussion = rootXML["ResultDiscussion"].childrenAsArray() return docs } } private extension XMLIndexer { /** - Returns an `[SourceKitRepresentable]` of `[String: SourceKitRepresentable]` items from `indexer` children, if any. + Returns an `[SourceKitVariant]` of `[UID:SourceKitVariant]` items from `indexer` children, if any. */ - func childrenAsArray() -> [SourceKitRepresentable]? { + func childrenAsArray() -> [SourceKitVariant]? { if children.isEmpty { return nil } let elements = children.flatMap { $0.element } - func dictionary(from element: SWXMLHash.XMLElement) -> [String:SourceKitRepresentable] { - return [element.name: element.text ?? ""] + func variant(from element: SWXMLHash.XMLElement) -> SourceKitVariant { + return [UID(element.name): SourceKitVariant(element.text ?? "")] } - return elements.map(dictionary(from:)) as [SourceKitRepresentable] + return elements.map(variant(from:)) } } // MARK: - migration support extension File { @available(*, unavailable, renamed: "process(dictionary:cursorInfoRequest:syntaxMap:)") - public func processDictionary(_ dictionary: [String: SourceKitRepresentable], cursorInfoRequest: sourcekitd_object_t? = nil, - syntaxMap: SyntaxMap? = nil) -> [String: SourceKitRepresentable] { + public func processDictionary(_ dictionary: [String: Any], cursorInfoRequest: SourceKitObject? = nil, + syntaxMap: SyntaxMap? = nil) -> [String: Any] { fatalError() } @available(*, unavailable, renamed: "parseDocumentationCommentBody(_:syntaxMap:)") - public func getDocumentationCommentBody(_ dictionary: [String: SourceKitRepresentable], syntaxMap: SyntaxMap) -> String? { + public func getDocumentationCommentBody(_ dictionary: [String: Any], syntaxMap: SyntaxMap) -> String? { fatalError() } } diff --git a/Source/SourceKittenFramework/JSONOutput.swift b/Source/SourceKittenFramework/JSONOutput.swift index 7a049b4d9..2414a771c 100644 --- a/Source/SourceKittenFramework/JSONOutput.swift +++ b/Source/SourceKittenFramework/JSONOutput.swift @@ -15,7 +15,8 @@ import Foundation - returns: JSON string representation of the input object. */ -public func toJSON(_ object: Any) -> String { +public func toJSON(_ object: Any?) -> String { + guard let object = object else { return "" } if let array = object as? [Any], array.isEmpty { return "[\n\n]" } @@ -35,29 +36,9 @@ public func toJSON(_ object: Any) -> String { - returns: JSON-serializable value. */ -public func toNSDictionary(_ dictionary: [String: SourceKitRepresentable]) -> NSDictionary { - var anyDictionary = [String: Any]() - for (key, object) in dictionary { - switch object { - case let object as [SourceKitRepresentable]: - anyDictionary[key] = object.map { toNSDictionary($0 as! [String: SourceKitRepresentable]) } - case let object as [[String: SourceKitRepresentable]]: - anyDictionary[key] = object.map { toNSDictionary($0) } - case let object as [String: SourceKitRepresentable]: - anyDictionary[key] = toNSDictionary(object) - case let object as String: - anyDictionary[key] = object - case let object as Int64: - anyDictionary[key] = NSNumber(value: object) - case let object as Bool: - anyDictionary[key] = NSNumber(value: object) - case let object as Any: - anyDictionary[key] = object - default: - fatalError("Should never happen because we've checked all SourceKitRepresentable types") - } - } - return anyDictionary.bridge() +@available(*, unavailable, message: "`toNSDictionary()` has been deprecated with `SourceKitRepresentable`.") +public func toNSDictionary(_ dictionary: [String: Any]) -> NSDictionary { + fatalError() } #if !os(Linux) diff --git a/Source/SourceKittenFramework/OffsetMap.swift b/Source/SourceKittenFramework/OffsetMap.swift index 710b0cf88..d98a96a5b 100644 --- a/Source/SourceKittenFramework/OffsetMap.swift +++ b/Source/SourceKittenFramework/OffsetMap.swift @@ -23,7 +23,7 @@ extension File { - returns: OffsetMap containing offset locations at which there are declarations that likely have documentation comments, but haven't been documented by SourceKitten yet. */ - public func makeOffsetMap(documentedTokenOffsets: [Int], dictionary: [String: SourceKitRepresentable]) -> OffsetMap { + public func makeOffsetMap(documentedTokenOffsets: [Int], dictionary: SourceKitVariant) -> OffsetMap { var offsetMap = OffsetMap() for offset in documentedTokenOffsets { offsetMap[offset] = 0 @@ -46,15 +46,15 @@ extension File { - returns: OffsetMap of potentially documented declaration offsets to its nearest parent offset. */ - private func mapOffsets(_ dictionary: [String: SourceKitRepresentable], offsetMap: OffsetMap) -> OffsetMap { + private func mapOffsets(_ dictionary: SourceKitVariant, offsetMap: OffsetMap) -> OffsetMap { var offsetMap = offsetMap // Only map if we're in the correct file - if let rangeStart = SwiftDocKey.getNameOffset(dictionary), - let rangeLength = SwiftDocKey.getNameLength(dictionary), + if let rangeStart = dictionary.nameOffset, + let rangeLength = dictionary.nameLength, shouldTreatAsSameFile(dictionary) { - let bodyLength = SwiftDocKey.getBodyLength(dictionary) ?? 0 - let rangeMax = Int(rangeStart + rangeLength + bodyLength) - let rangeStart = Int(rangeStart) + let bodyLength = dictionary.bodyLength ?? 0 + let rangeMax = rangeStart + rangeLength + bodyLength + let rangeStart = rangeStart let offsetsInRange = offsetMap.keys.filter { $0 >= rangeStart && $0 <= rangeMax } @@ -63,9 +63,9 @@ extension File { } } // Recurse! - if let substructure = SwiftDocKey.getSubstructure(dictionary) { + if let substructure = dictionary.subStructure { for subDict in substructure { - offsetMap = mapOffsets(subDict as! [String: SourceKitRepresentable], offsetMap: offsetMap) + offsetMap = mapOffsets(subDict, offsetMap: offsetMap) } } return offsetMap @@ -75,7 +75,7 @@ extension File { // MARK: - migration support extension File { @available(*, unavailable, renamed: "makeOffsetMap(documentedTokenOffsets:dictionary:)") - public func generateOffsetMap(_ documentedTokenOffsets: [Int], dictionary: [String: SourceKitRepresentable]) -> OffsetMap { + public func generateOffsetMap(_ documentedTokenOffsets: [Int], dictionary: [String: Any]) -> OffsetMap { fatalError() } } diff --git a/Source/SourceKittenFramework/Request.swift b/Source/SourceKittenFramework/Request.swift index 3a697aca3..e34c64393 100644 --- a/Source/SourceKittenFramework/Request.swift +++ b/Source/SourceKittenFramework/Request.swift @@ -6,6 +6,9 @@ // Copyright (c) 2015 JP Simard. All rights reserved. // +// swiftlint:disable file_length +// This file could easily be split up + import Dispatch import Foundation #if SWIFT_PACKAGE @@ -15,88 +18,8 @@ import SourceKit // swiftlint:disable file_length // This file could easily be split up -public protocol SourceKitRepresentable { - func isEqualTo(_ rhs: SourceKitRepresentable) -> Bool -} -extension Array: SourceKitRepresentable {} -extension Dictionary: SourceKitRepresentable {} -extension String: SourceKitRepresentable {} -extension Int64: SourceKitRepresentable {} -extension Bool: SourceKitRepresentable {} - -extension SourceKitRepresentable { - public func isEqualTo(_ rhs: SourceKitRepresentable) -> Bool { - switch self { - case let lhs as [SourceKitRepresentable]: - for (idx, value) in lhs.enumerated() { - if let rhs = rhs as? [SourceKitRepresentable], rhs[idx].isEqualTo(value) { - continue - } - return false - } - return true - case let lhs as [String: SourceKitRepresentable]: - for (key, value) in lhs { - if let rhs = rhs as? [String: SourceKitRepresentable], - let rhsValue = rhs[key], rhsValue.isEqualTo(value) { - continue - } - return false - } - return true - case let lhs as String: - return lhs == rhs as? String - case let lhs as Int64: - return lhs == rhs as? Int64 - case let lhs as Bool: - return lhs == rhs as? Bool - default: - fatalError("Should never happen because we've checked all SourceKitRepresentable types") - } - } -} - -private func fromSourceKit(_ sourcekitObject: sourcekitd_variant_t) -> SourceKitRepresentable? { - switch sourcekitd_variant_get_type(sourcekitObject) { - case SOURCEKITD_VARIANT_TYPE_ARRAY: - var array = [SourceKitRepresentable]() - _ = withUnsafeMutablePointer(to: &array) { arrayPtr in - sourcekitd_variant_array_apply_f(sourcekitObject, { index, value, context in - if let value = fromSourceKit(value), let context = context { - let localArray = context.assumingMemoryBound(to: [SourceKitRepresentable].self) - localArray.pointee.insert(value, at: Int(index)) - } - return true - }, arrayPtr) - } - return array - case SOURCEKITD_VARIANT_TYPE_DICTIONARY: - var dict = [String: SourceKitRepresentable]() - _ = withUnsafeMutablePointer(to: &dict) { dictPtr in - sourcekitd_variant_dictionary_apply_f(sourcekitObject, { key, value, context in - if let key = String(sourceKitUID: key!), let value = fromSourceKit(value), let context = context { - let localDict = context.assumingMemoryBound(to: [String: SourceKitRepresentable].self) - localDict.pointee[key] = value - } - return true - }, dictPtr) - } - return dict - case SOURCEKITD_VARIANT_TYPE_STRING: - return String(bytes: sourcekitd_variant_string_get_ptr(sourcekitObject), - length: sourcekitd_variant_string_get_length(sourcekitObject)) - case SOURCEKITD_VARIANT_TYPE_INT64: - return sourcekitd_variant_int64_get_value(sourcekitObject) - case SOURCEKITD_VARIANT_TYPE_BOOL: - return sourcekitd_variant_bool_get_value(sourcekitObject) - case SOURCEKITD_VARIANT_TYPE_UID: - return String(sourceKitUID: sourcekitd_variant_uid_get_value(sourcekitObject)) - case SOURCEKITD_VARIANT_TYPE_NULL: - return nil - default: - fatalError("Should never happen because we've checked all SourceKitRepresentable types") - } -} +@available(*, unavailable, message: "Use SourceKitVariant instead of SourceKitRepresentable") +typealias SourceKitRepresentable = Any /// Lazily and singly computed Void constants to initialize SourceKit once per session. private let initializeSourceKit: Void = { @@ -117,52 +40,7 @@ private let initializeSourceKitFailable: Void = { /// dispatch_semaphore_t used when waiting for sourcekitd to be restored. private var sourceKitWaitingRestoredSemaphore = DispatchSemaphore(value: 0) -private extension String { - /** - Cache SourceKit requests for strings from UIDs - - - returns: Cached UID string if available, nil otherwise. - */ - init?(sourceKitUID: sourcekitd_uid_t) { - let length = sourcekitd_uid_get_length(sourceKitUID) - let bytes = sourcekitd_uid_get_string_ptr(sourceKitUID) - if let uidString = String(bytes: bytes!, length: length) { - /* - `String` created by `String(UTF8String:)` is based on `NSString`. - `NSString` base `String` has performance penalty on getting `hashValue`. - Everytime on getting `hashValue`, it calls `decomposedStringWithCanonicalMapping` for - "Unicode Normalization Form D" and creates autoreleased `CFString (mutable)` and - `CFString (store)`. Those `CFString` are created every time on using `hashValue`, such as - using `String` for Dictionary's key or adding to Set. - - For avoiding those penalty, replaces with enum's rawValue String if defined in SourceKitten. - That does not cause calling `decomposedStringWithCanonicalMapping`. - */ - - self = String(uidString: uidString) - return - } - return nil - } - - /** - Assigns SourceKitten defined enum's rawValue String from string. - rawValue String if defined in SourceKitten, nil otherwise. - - - parameter uidString: String created from sourcekitd_uid_get_string_ptr(). - */ - init(uidString: String) { - if let rawValue = SwiftDocKey(rawValue: uidString)?.rawValue { - self = rawValue - } else if let rawValue = SwiftDeclarationKind(rawValue: uidString)?.rawValue { - self = rawValue - } else if let rawValue = SyntaxKind(rawValue: uidString)?.rawValue { - self = rawValue - } else { - self = "\(uidString)" - } - } - +internal extension String { /** Returns Swift's native String from NSUTF8StringEncoding bytes and length @@ -194,14 +72,14 @@ public enum Request { /// An `editor.open` request for the given File. case editorOpen(file: File) /// A `cursorinfo` request for an offset in the given file, using the `arguments` given. - case cursorInfo(file: String, offset: Int64, arguments: [String]) - /// A custom request by passing in the sourcekitd_object_t directly. - case customRequest(request: sourcekitd_object_t) + case cursorInfo(file: String, offset: Int, arguments: [String]) + /// A custom request by passing in the SourceKitObject directly. + case customRequest(request: SourceKitObject) /// A request generated by sourcekit using the yaml representation. case yamlRequest(yaml: String) /// A `codecomplete` request by passing in the file name, contents, offset /// for which to generate code completion options and array of compiler arguments. - case codeCompletionRequest(file: String, contents: String, offset: Int64, arguments: [String]) + case codeCompletionRequest(file: String, contents: String, offset: Int, arguments: [String]) /// ObjC Swift Interface case interface(file: String, uuid: String) /// Find USR @@ -209,120 +87,105 @@ public enum Request { /// Index case index(file: String, arguments: [String]) /// Format - case format(file: String, line: Int64, useTabs: Bool, indentWidth: Int64) + case format(file: String, line: Int, useTabs: Bool, indentWidth: Int) /// ReplaceText - case replaceText(file: String, offset: Int64, length: Int64, sourceText: String) + case replaceText(file: String, offset: Int, length: Int, sourceText: String) /// A documentation request for the given source text. case docInfo(text: String, arguments: [String]) /// A documentation request for the given module. case moduleInfo(module: String, arguments: [String]) - fileprivate var sourcekitObject: sourcekitd_object_t { - let dict: [sourcekitd_uid_t: sourcekitd_object_t?] + fileprivate var sourcekitObject: SourceKitObject { switch self { case .editorOpen(let file): if let path = file.path { - dict = [ - sourcekitd_uid_get_from_cstr("key.request"): sourcekitd_request_uid_create(sourcekitd_uid_get_from_cstr("source.request.editor.open")), - sourcekitd_uid_get_from_cstr("key.name"): sourcekitd_request_string_create(path), - sourcekitd_uid_get_from_cstr("key.sourcefile"): sourcekitd_request_string_create(path) + return [ + "key.request": UID.SourceRequest.editorOpen, + "key.name": path, + "key.sourcefile": path ] } else { - dict = [ - sourcekitd_uid_get_from_cstr("key.request"): sourcekitd_request_uid_create(sourcekitd_uid_get_from_cstr("source.request.editor.open")), - sourcekitd_uid_get_from_cstr("key.name"): sourcekitd_request_string_create(String(file.contents.hash)), - sourcekitd_uid_get_from_cstr("key.sourcetext"): sourcekitd_request_string_create(file.contents) + return [ + "key.request": UID.SourceRequest.editorOpen, + "key.name": String(file.contents.hash), + "key.sourcetext": file.contents ] } case .cursorInfo(let file, let offset, let arguments): - var compilerargs = arguments.map({ sourcekitd_request_string_create($0) }) - dict = [ - sourcekitd_uid_get_from_cstr("key.request"): sourcekitd_request_uid_create(sourcekitd_uid_get_from_cstr("source.request.cursorinfo")), - sourcekitd_uid_get_from_cstr("key.name"): sourcekitd_request_string_create(file), - sourcekitd_uid_get_from_cstr("key.sourcefile"): sourcekitd_request_string_create(file), - sourcekitd_uid_get_from_cstr("key.offset"): sourcekitd_request_int64_create(offset), - sourcekitd_uid_get_from_cstr("key.compilerargs"): sourcekitd_request_array_create(&compilerargs, compilerargs.count) + return [ + "key.request": UID.SourceRequest.cursorinfo, + "key.name": file, + "key.sourcefile": file, + "key.offset": offset, + "key.compilerargs": arguments ] case .customRequest(let request): return request case .yamlRequest(let yaml): - return sourcekitd_request_create_from_yaml(yaml, nil) + return SourceKitObject(object: sourcekitd_request_create_from_yaml(yaml, nil)) case .codeCompletionRequest(let file, let contents, let offset, let arguments): - var compilerargs = arguments.map({ sourcekitd_request_string_create($0) }) - dict = [ - sourcekitd_uid_get_from_cstr("key.request"): sourcekitd_request_uid_create(sourcekitd_uid_get_from_cstr("source.request.codecomplete")), - sourcekitd_uid_get_from_cstr("key.name"): sourcekitd_request_string_create(file), - sourcekitd_uid_get_from_cstr("key.sourcefile"): sourcekitd_request_string_create(file), - sourcekitd_uid_get_from_cstr("key.sourcetext"): sourcekitd_request_string_create(contents), - sourcekitd_uid_get_from_cstr("key.offset"): sourcekitd_request_int64_create(offset), - sourcekitd_uid_get_from_cstr("key.compilerargs"): sourcekitd_request_array_create(&compilerargs, compilerargs.count) + return [ + "key.request": UID.SourceRequest.codecomplete, + "key.name": file, + "key.sourcefile": file, + "key.sourcetext": contents, + "key.offset": offset, + "key.compilerargs": arguments ] case .interface(let file, let uuid): let arguments = ["-x", "objective-c", file, "-isysroot", sdkPath()] - var compilerargs = arguments.map({ sourcekitd_request_string_create($0) }) - dict = [ - sourcekitd_uid_get_from_cstr("key.request"): - sourcekitd_request_uid_create(sourcekitd_uid_get_from_cstr("source.request.editor.open.interface.header")), - sourcekitd_uid_get_from_cstr("key.name"): sourcekitd_request_string_create(uuid), - sourcekitd_uid_get_from_cstr("key.filepath"): sourcekitd_request_string_create(file), - sourcekitd_uid_get_from_cstr("key.compilerargs"): sourcekitd_request_array_create(&compilerargs, compilerargs.count) + return [ + "key.request": UID.SourceRequest.editorOpenInterfaceHeader, + "key.name": uuid, + "key.filepath": file, + "key.compilerargs": arguments ] case .findUSR(let file, let usr): - dict = [ - sourcekitd_uid_get_from_cstr("key.request"): sourcekitd_request_uid_create(sourcekitd_uid_get_from_cstr("source.request.editor.find_usr")), - sourcekitd_uid_get_from_cstr("key.usr"): sourcekitd_request_string_create(usr), - sourcekitd_uid_get_from_cstr("key.sourcefile"): sourcekitd_request_string_create(file) + return [ + "key.request": UID.SourceRequest.editorFind_Usr, + "key.usr": usr, + "key.sourcefile": file ] case .index(let file, let arguments): - var compilerargs = arguments.map({ sourcekitd_request_string_create($0) }) - dict = [ - sourcekitd_uid_get_from_cstr("key.request"): sourcekitd_request_uid_create(sourcekitd_uid_get_from_cstr("source.request.indexsource")), - sourcekitd_uid_get_from_cstr("key.sourcefile"): sourcekitd_request_string_create(file), - sourcekitd_uid_get_from_cstr("key.compilerargs"): sourcekitd_request_array_create(&compilerargs, compilerargs.count) + return [ + "key.request": UID.SourceRequest.indexsource, + "key.sourcefile": file, + "key.compilerargs": arguments ] case .format(let file, let line, let useTabs, let indentWidth): - let formatOptions = [ - sourcekitd_uid_get_from_cstr("key.editor.format.indentwidth"): sourcekitd_request_int64_create(indentWidth), - sourcekitd_uid_get_from_cstr("key.editor.format.tabwidth"): sourcekitd_request_int64_create(indentWidth), - sourcekitd_uid_get_from_cstr("key.editor.format.usetabs"): sourcekitd_request_int64_create(useTabs ? 1 : 0) - ] - var formatOptionsKeys = Array(formatOptions.keys.map({ $0 as sourcekitd_uid_t? })) - var formatOptionsValues = Array(formatOptions.values) - dict = [ - sourcekitd_uid_get_from_cstr("key.request"): sourcekitd_request_uid_create(sourcekitd_uid_get_from_cstr("source.request.editor.formattext")), - sourcekitd_uid_get_from_cstr("key.name"): sourcekitd_request_string_create(file), - sourcekitd_uid_get_from_cstr("key.line"): sourcekitd_request_int64_create(line), - sourcekitd_uid_get_from_cstr("key.editor.format.options"): - sourcekitd_request_dictionary_create(&formatOptionsKeys, &formatOptionsValues, formatOptions.count) + return [ + "key.request": UID.SourceRequest.editorFormattext, + "key.name": file, + "key.line": line, + "key.editor.format.options": [ + "key.editor.format.indentwidth": indentWidth, + "key.editor.format.tabwidth": indentWidth, + "key.editor.format.usetabs": (useTabs ? 1 : 0) + ] ] case .replaceText(let file, let offset, let length, let sourceText): - dict = [ - sourcekitd_uid_get_from_cstr("key.request"): sourcekitd_request_uid_create(sourcekitd_uid_get_from_cstr("source.request.editor.replacetext")), - sourcekitd_uid_get_from_cstr("key.name"): sourcekitd_request_string_create(file), - sourcekitd_uid_get_from_cstr("key.offset"): sourcekitd_request_int64_create(offset), - sourcekitd_uid_get_from_cstr("key.length"): sourcekitd_request_int64_create(length), - sourcekitd_uid_get_from_cstr("key.sourcetext"): sourcekitd_request_string_create(sourceText) + return [ + "key.request": UID.SourceRequest.editorReplacetext, + "key.name": file, + "key.offset": offset, + "key.length": length, + "key.sourcetext": sourceText ] case .docInfo(let text, let arguments): - var compilerargs = arguments.map({ sourcekitd_request_string_create($0) }) - dict = [ - sourcekitd_uid_get_from_cstr("key.request"): sourcekitd_request_uid_create(sourcekitd_uid_get_from_cstr("source.request.docinfo")), - sourcekitd_uid_get_from_cstr("key.name"): sourcekitd_request_string_create(NSUUID().uuidString), - sourcekitd_uid_get_from_cstr("key.compilerargs"): sourcekitd_request_array_create(&compilerargs, compilerargs.count), - sourcekitd_uid_get_from_cstr("key.sourcetext"): sourcekitd_request_string_create(text) + return [ + "key.request": UID.SourceRequest.docinfo, + "key.name": NSUUID().uuidString, + "key.compilerargs": arguments, + "key.sourcetext": text ] case .moduleInfo(let module, let arguments): - var compilerargs = arguments.map({ sourcekitd_request_string_create($0) }) - dict = [ - sourcekitd_uid_get_from_cstr("key.request"): sourcekitd_request_uid_create(sourcekitd_uid_get_from_cstr("source.request.docinfo")), - sourcekitd_uid_get_from_cstr("key.name"): sourcekitd_request_string_create(NSUUID().uuidString), - sourcekitd_uid_get_from_cstr("key.compilerargs"): sourcekitd_request_array_create(&compilerargs, compilerargs.count), - sourcekitd_uid_get_from_cstr("key.modulename"): sourcekitd_request_string_create(module) + return [ + "key.request": UID.SourceRequest.docinfo, + "key.name": NSUUID().uuidString, + "key.compilerargs": arguments, + "key.modulename": module ] } - var keys = Array(dict.keys.map({ $0 as sourcekitd_uid_t? })) - var values = Array(dict.values) - return sourcekitd_request_dictionary_create(&keys, &values, dict.count) } /** @@ -331,9 +194,9 @@ public enum Request { - parameter filePath: Path of the file to create request. - parameter arguments: Compiler arguments. - - returns: sourcekitd_object_t representation of the Request, if successful. + - returns: SourceKitObject representation of the Request, if successful. */ - internal static func cursorInfoRequest(filePath: String?, arguments: [String]) -> sourcekitd_object_t? { + internal static func cursorInfoRequest(filePath: String?, arguments: [String]) -> SourceKitObject? { if let path = filePath { return Request.cursorInfo(file: path, offset: 0, arguments: arguments).sourcekitObject } @@ -343,16 +206,16 @@ public enum Request { /** Send a Request.CursorInfo by updating its offset. Returns SourceKit response if successful. - - parameter cursorInfoRequest: sourcekitd_object_t representation of Request.CursorInfo + - parameter cursorInfoRequest: SourceKitObject representation of Request.CursorInfo - parameter offset: Offset to update request. - returns: SourceKit response if successful. */ - internal static func send(cursorInfoRequest: sourcekitd_object_t, atOffset offset: Int64) -> [String: SourceKitRepresentable]? { + internal static func send(cursorInfoRequest: SourceKitObject, atOffset offset: Int) -> SourceKitVariant? { if offset == 0 { return nil } - sourcekitd_request_dictionary_set_int64(cursorInfoRequest, sourcekitd_uid_get_from_cstr(SwiftDocKey.offset.rawValue), offset) + cursorInfoRequest.updateValue(offset, forKey: .offset) return try? Request.customRequest(request: cursorInfoRequest).failableSend() } @@ -361,11 +224,9 @@ public enum Request { - returns: SourceKit output as a dictionary. */ - public func send() -> [String: SourceKitRepresentable] { - initializeSourceKit - let response = sourcekitd_send_request_sync(sourcekitObject) - defer { sourcekitd_response_dispose(response!) } - return fromSourceKit(sourcekitd_response_get_value(response!)) as! [String: SourceKitRepresentable] + @available(*, unavailable, message: "Use `failableSend()` instead of `send()`") + public func send() -> [String: Any] { + fatalError() } /// A enum representation of SOURCEKITD_ERROR_* @@ -404,23 +265,23 @@ public enum Request { } /** - Sends the request to SourceKit and return the response as an [String: SourceKitRepresentable]. + Sends the request to SourceKit and return the response as an SourceKitVariant. - - returns: SourceKit output as a dictionary. - - throws: Request.Error on fail () - */ - public func failableSend() throws -> [String: SourceKitRepresentable] { + - returns: SourceKit output as a SourceKitVariant. + - throws: Request.Error on fail () + */ + public func failableSend() throws -> SourceKitVariant { initializeSourceKitFailable - let response = sourcekitd_send_request_sync(sourcekitObject) - defer { sourcekitd_response_dispose(response!) } + let response = sourcekitd_send_request_sync(sourcekitObject.object!) if sourcekitd_response_is_error(response!) { let error = Request.Error(response: response!) if case .connectionInterrupted = error { _ = sourceKitWaitingRestoredSemaphore.wait(timeout: DispatchTime.now() + 10) } + sourcekitd_response_dispose(response!) throw error } - return fromSourceKit(sourcekitd_response_get_value(response!)) as! [String: SourceKitRepresentable] + return SourceKitVariant(variant: sourcekitd_response_get_value(response!), response: response!) } } @@ -428,28 +289,25 @@ public enum Request { extension Request: CustomStringConvertible { /// A textual representation of `Request`. - public var description: String { return String(validatingUTF8: sourcekitd_request_description_copy(sourcekitObject)!)! } + public var description: String { return sourcekitObject.description } } -private func interfaceForModule(_ module: String, compilerArguments: [String]) -> [String: SourceKitRepresentable] { - var compilerargs = compilerArguments.map { sourcekitd_request_string_create($0) } - let dict = [ - sourcekitd_uid_get_from_cstr("key.request"): sourcekitd_request_uid_create(sourcekitd_uid_get_from_cstr("source.request.editor.open.interface")), - sourcekitd_uid_get_from_cstr("key.name"): sourcekitd_request_string_create(NSUUID().uuidString), - sourcekitd_uid_get_from_cstr("key.compilerargs"): sourcekitd_request_array_create(&compilerargs, compilerargs.count), - sourcekitd_uid_get_from_cstr("key.modulename"): sourcekitd_request_string_create("SourceKittenFramework.\(module)") +private func interfaceForModule(_ module: String, compilerArguments: [String]) throws -> SourceKitVariant { + let sourceKitObject: SourceKitObject = [ + "key.request": UID.SourceRequest.editorOpenInterface, + "key.name": NSUUID().uuidString, + "key.compilerargs": compilerArguments, + "key.modulename": "SourceKittenFramework.\(module)" ] - var keys = Array(dict.keys.map({ $0 as sourcekitd_uid_t? })) - var values = Array(dict.values) - return Request.customRequest(request: sourcekitd_request_dictionary_create(&keys, &values, dict.count)).send() + return try Request.customRequest(request: sourceKitObject).failableSend() } extension String { - fileprivate func extractFreeFunctions(inSubstructure substructure: [[String: SourceKitRepresentable]]) -> [String] { + fileprivate func extractFreeFunctions(inSubstructure substructure: [SourceKitVariant]) -> [String] { return substructure.filter({ - SwiftDeclarationKind(rawValue: SwiftDocKey.getKind($0)!) == .functionFree + $0.kind == UID.SourceLangSwiftDecl.functionFree }).flatMap { function -> String? in - let fullFunctionName = function["key.name"] as! String + let fullFunctionName = function.name! let name = fullFunctionName.substring(to: fullFunctionName.range(of: "(")!.lowerBound) let unsupportedFunctions = [ "clang_executeOnThread", @@ -461,13 +319,13 @@ extension String { } var parameters = [String]() - if let functionSubstructure = SwiftDocKey.getSubstructure(function) { + if let functionSubstructure = function.subStructure { for parameterStructure in functionSubstructure { - parameters.append((parameterStructure as! [String: SourceKitRepresentable])["key.typename"] as! String) + parameters.append(parameterStructure.typeName!) } } var returnTypes = [String]() - if let offset = SwiftDocKey.getOffset(function), let length = SwiftDocKey.getLength(function) { + if let offset = function.offset, let length = function.length { let start = index(startIndex, offsetBy: Int(offset)) let end = index(start, offsetBy: Int(length)) let functionDeclaration = substring(with: start.. String { - let sourceKitResponse = interfaceForModule(module, compilerArguments: compilerArguments) - let substructure = SwiftDocKey.getSubstructure(Structure(sourceKitResponse: sourceKitResponse).dictionary)!.map({ $0 as! [String: SourceKitRepresentable] }) - let source = sourceKitResponse["key.sourcetext"] as! String +internal func libraryWrapperForModule(_ module: String, loadPath: String, linuxPath: String?, spmModule: String, compilerArguments: [String]) throws -> String { + let sourceKitVariant = try interfaceForModule(module, compilerArguments: compilerArguments) + let substructure = sourceKitVariant.subStructure ?? [] + let source = sourceKitVariant.sourceText! let freeFunctions = source.extractFreeFunctions(inSubstructure: substructure) let spmImport = "#if SWIFT_PACKAGE\nimport \(spmModule)\n#endif\n" let library: String @@ -524,7 +382,7 @@ extension Request { public static func CursorInfo(file: String, offset: Int64, arguments: [String]) -> Request { fatalError() } @available(*, unavailable, renamed: "customRequest(request:)") - public static func CustomRequest(_: sourcekitd_object_t) -> Request { fatalError() } + public static func CustomRequest(_: SourceKitObject) -> Request { fatalError() } @available(*, unavailable, renamed: "codeCompletionRequest(file:contents:offset:arguments:)") public static func CodeCompletionRequest(file: String, contents: String, offset: Int64, arguments: [String]) -> Request { fatalError() } diff --git a/Source/SourceKittenFramework/SourceKitObject.swift b/Source/SourceKittenFramework/SourceKitObject.swift new file mode 100644 index 000000000..fb32a26d7 --- /dev/null +++ b/Source/SourceKittenFramework/SourceKitObject.swift @@ -0,0 +1,113 @@ +// +// SourceKitObject.swift +// SourceKitten +// +// Created by Norio Nomura on 11/29/16. +// Copyright © 2016 SourceKitten. All rights reserved. +// + +import Foundation +#if SWIFT_PACKAGE + import SourceKit +#endif + +public protocol SourceKitObjectConvertible { + var object: sourcekitd_object_t? { get } +} + +extension Array: SourceKitObjectConvertible { + public var object: sourcekitd_object_t? { + guard let first = first, first is SourceKitObjectConvertible else { return nil } + let objects: [sourcekitd_object_t?] = map { ($0 as! SourceKitObjectConvertible).object } + return sourcekitd_request_array_create(objects, objects.count) + } +} + +extension Dictionary: SourceKitObjectConvertible { + public var object: sourcekitd_object_t? { + guard let (key, value) = first, key is UID.Key, value is SourceKitObjectConvertible else { return nil } + let keys: [sourcekitd_uid_t?] = self.map { ($0.key as! UID.Key).uid.uid } + let values: [sourcekitd_object_t?] = self.map { ($0.value as! SourceKitObjectConvertible).object } + return sourcekitd_request_dictionary_create(keys, values, count) + } +} + +extension Int: SourceKitObjectConvertible { + public var object: sourcekitd_object_t? { + return sourcekitd_request_int64_create(Int64(self)) + } +} + +extension String: SourceKitObjectConvertible { + public var object: sourcekitd_object_t? { + return sourcekitd_request_string_create(self) + } +} + +/// Swift representation of sourcekitd_object_t +public struct SourceKitObject { + public let object: sourcekitd_object_t? + + /// Updates the value stored in the dictionary for the given key, + /// or adds a new key-value pair if the key does not exist. + /// + /// - Parameters: + /// - value: The new value to add to the dictionary. + /// - key: The key to associate with value. If key already exists in the dictionary, + /// value replaces the existing associated value. If key isn't already a key of the dictionary + public func updateValue(_ value: SourceKitObjectConvertible, forKey key: UID.Key) { + precondition(object != nil) + precondition(value.object != nil) + sourcekitd_request_dictionary_set_value(object!, key.uid.uid, value.object!) + } +} + +extension SourceKitObject: SourceKitObjectConvertible {} + +// MARK: - CustomStringConvertible +extension SourceKitObject: CustomStringConvertible { + public var description: String { + guard let object = object else { return "" } + let bytes = sourcekitd_request_description_copy(object)! + let length = Int(strlen(bytes)) + return String(bytesNoCopy: bytes, length: length, encoding: .utf8, freeWhenDone: true)! + } +} + +// MARK: - ExpressibleByArrayLiteral +extension SourceKitObject: ExpressibleByArrayLiteral { + public init(arrayLiteral elements: SourceKitObject...) { + object = elements.object + } +} + +// MARK: - ExpressibleByDictionaryLiteral +extension SourceKitObject: ExpressibleByDictionaryLiteral { + public init(dictionaryLiteral elements: (UID.Key, SourceKitObjectConvertible)...) { + let keys: [sourcekitd_uid_t?] = elements.map { $0.0.uid.uid } + let values: [sourcekitd_object_t?] = elements.map { $0.1.object } + object = sourcekitd_request_dictionary_create(keys, values, elements.count) + } +} + +// MARK: - ExpressibleByIntegerLiteral +extension SourceKitObject: ExpressibleByIntegerLiteral { + public init(integerLiteral value: IntegerLiteralType) { + object = value.object + } +} + +// MARK: - ExpressibleByStringLiteral +extension SourceKitObject: ExpressibleByStringLiteral { + public init(stringLiteral value: String) { + object = value.object + } + + public init(extendedGraphemeClusterLiteral value: String) { + object = value.object + } + + public init(unicodeScalarLiteral value: String) { + object = value.object + } +} diff --git a/Source/SourceKittenFramework/SourceKitVariant.swift b/Source/SourceKittenFramework/SourceKitVariant.swift new file mode 100644 index 000000000..0bb109200 --- /dev/null +++ b/Source/SourceKittenFramework/SourceKitVariant.swift @@ -0,0 +1,770 @@ +// +// SourceKitVariant.swift +// SourceKitten +// +// Created by Norio Nomura on 10/17/16. +// Copyright © 2016 SourceKitten. All rights reserved. +// + +import Foundation +#if SWIFT_PACKAGE +import SourceKit +#endif + +// swiftlint:disable file_length + +/// Represent sourcekitd_variant_t as Value Type +public struct SourceKitVariant { + fileprivate var box: _VariantBox +} + +// MARK: - Basic properties of SourceKitVariant +extension SourceKitVariant { + public var array: [SourceKitVariant]? { + get { return box.array } + set { + prepareMutation() + box.array = newValue + } + } + + public var dictionary: [UID:SourceKitVariant]? { + get { return box.dictionary } + set { + prepareMutation() + box.dictionary = newValue + } + } + + public var string: String? { + get { return box.string } + set { + prepareMutation() + box.string = newValue + } + } + + public var int: Int? { + get { return box.int } + set { + prepareMutation() + box.int = newValue + } + } + + public var bool: Bool? { + get { return box.bool } + set { + prepareMutation() + box.bool = newValue + } + } + + public var uid: UID? { + get { return box.uid } + set { + prepareMutation() + box.uid = newValue + } + } + + public var any: Any? { return box.any } + + public subscript(string: String) -> SourceKitVariant? { + get { return box.dictionary?[UID(string)] } + set { + prepareMutation() + box.dictionary?[UID(string)] = newValue + } + } + + public subscript(uid: UID) -> SourceKitVariant? { + get { return box.dictionary?[uid] } + set { + prepareMutation() + box.dictionary?[uid] = newValue + } + } + + public subscript(index: Int) -> SourceKitVariant? { + get { return box.array?[index] } + set { + prepareMutation() + box.array?[index] = newValue! + } + } +} + +// MARK: - Convenient properties for well known UIDs +extension SourceKitVariant { + public subscript(key: UID.Key) -> SourceKitVariant? { + get { return box.dictionary?[key.uid] } + set { + prepareMutation() + box.dictionary?[key.uid] = newValue + } + } + + @discardableResult + mutating public func removeValue(forKey key: UID.Key) -> SourceKitVariant? { + prepareMutation() + var dictionary = box.dictionary + let result = dictionary?.removeValue(forKey: key.uid) + box.dictionary = dictionary + return result + } + + /// Accessibility (UID.SourceLangSwiftAccessibility). + public var accessibility: UID.SourceLangSwiftAccessibility? { + return self[.accessibility]?.uid.map(UID.SourceLangSwiftAccessibility.init) + } + /// Annotated declaration (String). + public var annotatedDeclaration: String? { + return self[.annotated_decl]?.string + } + /// associatedUsrs (String). + public var associatedUsrs: String? { + return self[.associated_usrs]?.string + } + /// Attributes ([SourceKitVariant]). + public var attributes: [SourceKitVariant]? { + return self[.attributes]?.array + } + /// Attribute (UID.SourceDeclAttribute). + public var attribute: UID.SourceDeclAttribute? { + return self[.attribute]?.uid.map(UID.SourceDeclAttribute.init) + } + /// Body length (Int). + public var bodyLength: Int? { + return self[.bodylength]?.int + } + /// Body offset (Int). + public var bodyOffset: Int? { + return self[.bodyoffset]?.int + } + /// context (String). + public var context: String? { + return self[.context]?.string + } + /// description (String). + public var description: String? { + return self[.description]?.string + } + /// Diagnostic stage (UID.SourceDiagnosticStageSwift). + public var diagnosticStage: UID.SourceDiagnosticStageSwift? { + return self[.diagnostic_stage]?.uid.map(UID.SourceDiagnosticStageSwift.init) + } + /// docBrief (String). + public var docBrief: String? { + return self[.docBrief]?.string + } + /// File path (String). + public var filePath: String? { + return self[.filepath]?.string + } + /// Full XML docs (String). + public var docFullAsXML: String? { + return self[.docFull_As_Xml]?.string + } + /// Inheritedtype ([SourceKitVariant]) + public var inheritedTypes: [SourceKitVariant]? { + return self[.inheritedtypes]?.array + } + /// Kind (UID). + public var kind: UID? { + return self[.kind]?.uid + } + /// Length (Int). + public var length: Int? { + return self[.length]?.int + } + /// ModuleName (String). + public var moduleName: String? { + return self[.modulename]?.string + } + /// Name (String). + public var name: String? { + return self[.name]?.string + } + /// Name length (Int). + public var nameLength: Int? { + return self[.namelength]?.int + } + /// Name offset (Int). + public var nameOffset: Int? { + return self[.nameoffset]?.int + } + /// Offset (Int). + public var offset: Int? { + return self[.offset]?.int + } + /// results ([SourceKitVariant]). + public var results: [SourceKitVariant]? { + get { return self[.results]?.array } + set { self[.results] = SourceKitVariant(newValue) } + } + /// sourcetext + public var sourceText: String? { + return self[.sourcetext]?.string + } + /// Substructure ([SourceKitVariant]). + public var subStructure: [SourceKitVariant]? { + get { return self[.substructure]?.array } + set { self[.substructure] = SourceKitVariant(newValue) } + } + /// Syntax map ([SourceKitVariant]). + public var syntaxMap: [SourceKitVariant]? { + return self[.syntaxmap]?.array + } + /// Type name (String). + public var typeName: String? { + return self[.typename]?.string + } +} + +// MARK: - Convenient properties for Custom Keys +extension SourceKitVariant { + fileprivate struct Custom { + static let docColumn = UID("key.doc.column") + static let documentationComment = UID("key.doc.comment") + static let docDeclaration = UID("key.doc.declaration") + static let docDiscussion = UID("key.doc.discussion") + static let docFile = UID("key.doc.file") + static let docLine = UID("key.doc.line") + static let docName = UID("key.doc.name") + static let docParameters = UID("key.doc.parameters") + static let docResultDiscussion = UID("key.doc.result_discussion") + static let docType = UID("key.doc.type") + // static let usr = UID("key.usr") + static let parsedDeclaration = UID("key.parsed_declaration") + static let parsedScopeEnd = UID("key.parsed_scope.end") + static let parsedScopeStart = UID("key.parsed_scope.start") + static let swiftDeclaration = UID("key.swift_declaration") + static let alwaysDeprecated = UID("key.always_deprecated") + static let alwaysUnavailable = UID("key.always_unavailable") + static let deprecationMessage = UID("key.deprecation_message") + static let unavailableMessage = UID("key.unavailable_message") + } + + /// Column where the token's declaration begins (Int). + public var docColumn: Int? { + get { return self[Custom.docColumn]?.int } + set { self[Custom.docColumn] = SourceKitVariant(newValue) } + } + + /// Documentation comment (String). + public var documentationComment: String? { + get { return self[Custom.documentationComment]?.string } + set { self[Custom.documentationComment] = SourceKitVariant(newValue) } + } + + /// Declaration of documented token (String). + public var docDeclaration: String? { + get { return self[Custom.docDeclaration]?.string } + set { self[Custom.docDeclaration] = SourceKitVariant(newValue) } + } + + /// Discussion documentation of documented token ([SourceKitVariant]). + public var docDiscussion: [SourceKitVariant]? { + get { return self[Custom.docDiscussion]?.array } + set { self[Custom.docDiscussion] = SourceKitVariant(newValue) } + } + + /// File where the documented token is located (String). + public var docFile: String? { + get { return self[Custom.docFile]?.string } + set { self[Custom.docFile] = SourceKitVariant(newValue) } + } + + /// Line where the token's declaration begins (Int). + public var docLine: Int? { + get { return self[Custom.docLine]?.int } + set { self[Custom.docLine] = SourceKitVariant(newValue) } + } + + /// Name of documented token (String). + public var docName: String? { + get { return self[Custom.docName]?.string } + set { self[Custom.docName] = SourceKitVariant(newValue) } + } + + /// Parameters of documented token ([SourceKitVariant]). + public var docParameters: [SourceKitVariant]? { + get { return self[Custom.docParameters]?.array } + set { self[Custom.docParameters] = SourceKitVariant(newValue) } + } + + /// Doc result discussion ([SourceKitVariant]). + public var docResultDiscussion: [SourceKitVariant]? { + get { return self[Custom.docResultDiscussion]?.array } + set { self[Custom.docResultDiscussion] = SourceKitVariant(newValue) } + } + + /// Type of documented token (String). + public var docType: String? { + get { return self[Custom.docType]?.string } + set { self[Custom.docType] = SourceKitVariant(newValue) } + } + + /// USR (String). + public var usr: String? { + get { return self[.usr]?.string } + set { self[.usr] = SourceKitVariant(newValue) } + } + + /// Parsed Declaration (String) + public var parsedDeclaration: String? { + get { return self[Custom.parsedDeclaration]?.string } + set { self[Custom.parsedDeclaration] = SourceKitVariant(newValue) } + } + + /// Parsed scope end (Int). + public var parsedScopeEnd: Int? { + get { return self[Custom.parsedScopeEnd]?.int } + set { self[Custom.parsedScopeEnd] = SourceKitVariant(newValue) } + } + + /// Parsed scope start (Int). + public var parsedScopeStart: Int? { + get { return self[Custom.parsedScopeStart]?.int } + set { self[Custom.parsedScopeStart] = SourceKitVariant(newValue) } + } + + /// Swift Declaration (String). + public var swiftDeclaration: String? { + get { return self[Custom.swiftDeclaration]?.string } + set { self[Custom.swiftDeclaration] = SourceKitVariant(newValue) } + } + + /// Always deprecated (Bool). + public var alwaysDeprecated: Bool? { + get { return self[Custom.alwaysDeprecated]?.bool } + set { self[Custom.alwaysDeprecated] = SourceKitVariant(newValue) } + } + + /// Always unavailable (Bool). + public var alwaysUnavailable: Bool? { + get { return self[Custom.alwaysUnavailable]?.bool } + set { self[Custom.alwaysUnavailable] = SourceKitVariant(newValue) } + } + + /// Deprecation message (String). + public var deprecationMessage: String? { + get { return self[Custom.deprecationMessage]?.string } + set { self[Custom.deprecationMessage] = SourceKitVariant(newValue) } + } + + /// Unavailable message (String). + public var unavailableMessage: String? { + get { return self[Custom.unavailableMessage]?.string } + set { self[Custom.unavailableMessage] = SourceKitVariant(newValue) } + } + +} + +let knownUIDsOfCustomKey: Set = [ + SourceKitVariant.Custom.docColumn, + SourceKitVariant.Custom.documentationComment, + SourceKitVariant.Custom.docDeclaration, + SourceKitVariant.Custom.docDiscussion, + SourceKitVariant.Custom.docFile, + SourceKitVariant.Custom.docLine, + SourceKitVariant.Custom.docName, + SourceKitVariant.Custom.docParameters, + SourceKitVariant.Custom.docResultDiscussion, + SourceKitVariant.Custom.docType, + // SourceKitVariant.Custom.usr, + SourceKitVariant.Custom.parsedDeclaration, + SourceKitVariant.Custom.parsedScopeEnd, + SourceKitVariant.Custom.parsedScopeStart, + SourceKitVariant.Custom.swiftDeclaration, + SourceKitVariant.Custom.alwaysDeprecated, + SourceKitVariant.Custom.alwaysUnavailable, + SourceKitVariant.Custom.deprecationMessage, + SourceKitVariant.Custom.unavailableMessage, + // used in result of `parseFullXMLDocs(_:`) + UID("name"), + UID("discussion") +] + +// MARK: - ExpressibleByArrayLiteral +extension SourceKitVariant: ExpressibleByArrayLiteral { + public init(arrayLiteral elements: SourceKitVariant...) { + box = _VariantBox(variant: .array(elements)) + } +} + +// MARK: - ExpressibleByBooleanLiteral +extension SourceKitVariant: ExpressibleByBooleanLiteral { + public init(booleanLiteral value: BooleanLiteralType) { + box = _VariantBox(variant: .bool(value)) + } +} + +// MARK: - ExpressibleByDictionaryLiteral +extension SourceKitVariant: ExpressibleByDictionaryLiteral { + public init(dictionaryLiteral elements: (UID, SourceKitVariant)...) { + var dictionary = [UID: SourceKitVariant](minimumCapacity: elements.count) + elements.forEach { dictionary[$0.0] = $0.1 } + box = _VariantBox(variant: .dictionary(dictionary)) + } +} + +// MARK: - ExpressibleByIntegerLiteral +extension SourceKitVariant: ExpressibleByIntegerLiteral { + public init(integerLiteral value: IntegerLiteralType) { + box = _VariantBox(variant: .int64(Int64(value))) + } +} + +// MARK: - ExpressibleByStringLiteral +extension SourceKitVariant: ExpressibleByStringLiteral { + public init(stringLiteral value: StringLiteralType) { + box = _VariantBox(variant: .string(value)) + } + + public init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterType) { + box = _VariantBox(variant: .string(value)) + } + + public init(unicodeScalarLiteral value: UnicodeScalarType) { + box = _VariantBox(variant: .string(value)) + } +} + +// MARK: - Equatable +extension SourceKitVariant: Equatable { + public static func == (lhs: SourceKitVariant, rhs: SourceKitVariant) -> Bool { + return lhs.box == rhs.box + } +} + +// MARK: - Initializers +extension SourceKitVariant { + internal init(_ array: [SourceKitVariant]?) { + box = _VariantBox(variant: array.map(_VariantCore.array) ?? .none) + } + + internal init(_ dictionary: [UID:SourceKitVariant]? = [:]) { + box = _VariantBox(variant: dictionary.map(_VariantCore.dictionary) ?? .none) + } + + internal init(_ string: String?) { + box = _VariantBox(variant: string.map(_VariantCore.string) ?? .none) + } + + internal init(_ int: Int?) { + box = _VariantBox(variant: int.map({ _VariantCore.int64(Int64($0)) }) ?? .none) + } + + internal init(_ bool: Bool?) { + box = _VariantBox(variant: bool.map(_VariantCore.bool) ?? .none) + } + + internal init(_ uid: UID) { + box = _VariantBox(variant: .uid(uid)) + } + + internal init(variant: sourcekitd_variant_t, response: sourcekitd_response_t) { + box = _VariantBox(variant: .variant(variant, _ResponseBox(response))) + } +} + +// MARK: - Implementation +extension SourceKitVariant { + fileprivate enum _VariantCore { + case variant(sourcekitd_variant_t, _ResponseBox) + case array([SourceKitVariant]) + case dictionary([UID:SourceKitVariant]) + case string(String) + case int64(Int64) + case bool(Bool) + case uid(UID) + case none + + fileprivate init(sourcekitObject: sourcekitd_variant_t, response: _ResponseBox) { + switch sourcekitd_variant_get_type(sourcekitObject) { + case SOURCEKITD_VARIANT_TYPE_ARRAY: + var array = [SourceKitVariant]() + _ = __sourcekitd_variant_array_apply(sourcekitObject) { index, value in + array.insert(SourceKitVariant(variant: value, response: response), at:Int(index)) + return true + } + self = .array(array) + case SOURCEKITD_VARIANT_TYPE_DICTIONARY: + var count: Int = 0 + _ = __sourcekitd_variant_dictionary_apply(sourcekitObject) { _, _ in + count += 1 + return true + } + var dictionary = [UID: SourceKitVariant](minimumCapacity: count) + _ = __sourcekitd_variant_dictionary_apply(sourcekitObject) { uid, value in + if let uid = uid { + dictionary[UID(uid)] = SourceKitVariant(variant: value, response: response) + } + return true + } + self = .dictionary(dictionary) + case SOURCEKITD_VARIANT_TYPE_STRING: + let length = sourcekitd_variant_string_get_length(sourcekitObject) + let ptr = sourcekitd_variant_string_get_ptr(sourcekitObject) + self = String(bytes: ptr!, length: length).map(_VariantCore.string) ?? .none + case SOURCEKITD_VARIANT_TYPE_INT64: + self = .int64(sourcekitd_variant_int64_get_value(sourcekitObject)) + case SOURCEKITD_VARIANT_TYPE_BOOL: + self = .bool(sourcekitd_variant_bool_get_value(sourcekitObject)) + case SOURCEKITD_VARIANT_TYPE_UID: + self = .uid(UID(sourcekitd_variant_uid_get_value(sourcekitObject))) + case SOURCEKITD_VARIANT_TYPE_NULL: + self = .none + default: + fatalError("Should never happen because we've checked all SOURCEKITD_VARIANT_TYPE") + } + } + } + + private init(variant: sourcekitd_variant_t, response: _ResponseBox) { + box = _VariantBox(variant: .variant(variant, response)) + } + + fileprivate final class _VariantBox { + private var _core: _VariantCore + + fileprivate init(variant: _VariantCore) { _core = variant } + + fileprivate func resolveType() -> _VariantCore { + if case let .variant(sourcekitObject, response) = _core { + _core = _VariantCore(sourcekitObject: sourcekitObject, response: response) + } + return _core + } + + var array: [SourceKitVariant]? { + get { + if case let .array(array) = _core { return array } + if case let .array(array) = resolveType() { return array } + return nil + } + set { + if case .array = _core, let newValue = newValue { + _core = .array(newValue) + } else { + fatalError() + } + } + } + + var dictionary: [UID:SourceKitVariant]? { + get { + if case let .dictionary(dictionary) = _core { return dictionary } + if case let .dictionary(dictionary) = resolveType() { return dictionary } + return nil + } + set { + if case .dictionary = _core, let newValue = newValue { + _core = .dictionary(newValue) + } else { + fatalError() + } + } + } + + var string: String? { + get { + if case let .string(string) = _core { return string } + if case let .uid(uid) = _core { return uid.string } + switch resolveType() { + case let .string(string): return string + case let .uid(uid): return uid.string + default: return nil + } + } + set { + if case .string = _core, let newValue = newValue { + _core = .string(newValue) + } else if case .uid = _core, let newValue = newValue { + _core = .uid(UID(newValue)) + } else { + fatalError() + } + } + } + + var int: Int? { + get { + if case let .int64(int64) = _core { return Int(int64) } + if case let .int64(int64) = resolveType() { return Int(int64) } + return nil + } + set { + if case .int64 = _core, let newValue = newValue { + _core = .int64(Int64(newValue)) + } else { + fatalError() + } + } + } + + var int64: Int64? { + get { + if case let .int64(int64) = _core { return int64 } + if case let .int64(int64) = resolveType() { return int64 } + return nil + } + set { + if case .int64 = _core, let newValue = newValue { + _core = .int64(newValue) + } else { + fatalError() + } + } + } + + var bool: Bool? { + get { + if case let .bool(bool) = _core { return bool } + if case let .bool(bool) = resolveType() { return bool } + return nil + } + set { + if case .bool = _core, let newValue = newValue { + _core = .bool(newValue) + } else { + fatalError() + } + } + } + + var uid: UID? { + get { + if case let .uid(uid) = _core { return uid } + if case let .uid(uid) = resolveType() { return uid } + return nil + } + set { + if case .uid = _core, let newValue = newValue { + _core = .uid(newValue) + } else { + fatalError() + } + } + } + + var any: Any? { + switch _core { + case let .variant(sourcekitObject, response): + _core = _VariantCore(sourcekitObject: sourcekitObject, response: response) + return self.any + case let .array(array): + return array.flatMap { $0.any } + case let .dictionary(dictionary): + var anyDictionary = [String: Any](minimumCapacity: dictionary.count) + for (key, value) in dictionary { + anyDictionary[key.string] = value.any + } + return anyDictionary + case let .string(string): + return string + case let .int64(int64): + return Int(int64) + case let .bool(bool): + return bool + case let .uid(uid): + return uid.string + case .none: + return nil + } + } + + fileprivate func copy() -> _VariantBox { + return .init(variant: _core) + } + } + + fileprivate final class _ResponseBox { + private let response: sourcekitd_response_t + init(_ response: sourcekitd_response_t) { self.response = response } + deinit { sourcekitd_response_dispose(response) } + } +} + +// MARK: - Copy on write +extension SourceKitVariant { + fileprivate mutating func prepareMutation() { + if !isKnownUniquelyReferenced(&box) { + box = box.copy() + } + } +} + +// MARK: - Equatable +extension SourceKitVariant._VariantBox: Equatable { + public static func == (lhs: SourceKitVariant._VariantBox, rhs: SourceKitVariant._VariantBox) -> Bool { + switch (lhs.resolveType(), rhs.resolveType()) { + case let (.array(lhs), .array(rhs)): return lhs == rhs + case let (.dictionary(lhs), .dictionary(rhs)): return lhs == rhs + case let (.string(lhs), .string(rhs)): return lhs == rhs + case let (.int64(lhs), .int64(rhs)): return lhs == rhs + case let (.bool(lhs), .bool(rhs)): return lhs == rhs + case let (.uid(lhs), .uid(rhs)): return lhs == rhs + case (.none, .none): return true + default: return false + } + } +} + +// MARK: - sourcekitd_variant_*_apply +// It is hard to pass multiple Swift objects in context parameter on calling +// sourcekitd's `*_apply_f` functions. +// So, I added `*_apply` compatible functions that passing Swift closure as +// context and calling them in C function. +func __sourcekitd_variant_array_apply( // swiftlint:disable:this identifier_name + _ array: sourcekitd_variant_t, + _ applier: @escaping (Int, sourcekitd_variant_t) -> Bool) -> Bool { + typealias ArrayApplier = (Int, sourcekitd_variant_t) -> Bool + var applier = applier + return withUnsafeMutablePointer(to: &applier) { context in + sourcekitd_variant_array_apply_f(array, { index, value, context in + if let context = context { + let applier = context.assumingMemoryBound(to: ArrayApplier.self).pointee + return applier(index, value) + } + return true + }, context) + } +} + +func __sourcekitd_variant_dictionary_apply( // swiftlint:disable:this identifier_name + _ dict: sourcekitd_variant_t, + _ applier: @escaping (sourcekitd_uid_t?, sourcekitd_variant_t) -> Bool) -> Bool { + typealias DictionaryApplier = (sourcekitd_uid_t?, sourcekitd_variant_t) -> Bool + var applier = applier + return withUnsafeMutablePointer(to: &applier) { context in + sourcekitd_variant_dictionary_apply_f(dict, { key, value, context in + if let context = context { + let applier = context.assumingMemoryBound(to: DictionaryApplier.self).pointee + return applier(key, value) + } + return true + }, context) + } +} + +extension SourceKitVariant { + /// Merged SourceKitVariant + /// If both of variants has same key, value will be overwritten by one of given variant. + /// + /// - Parameters: + /// - variant: SourceKitVariant + /// - Returns: Merged SourceKitVariant + func merging(with variant: SourceKitVariant?) -> SourceKitVariant { + if var dictionary = dictionary, + let dict2 = variant?.dictionary { + for (key, value) in dict2 { + dictionary[key] = value + } + return SourceKitVariant(dictionary) + } + return self + } +} diff --git a/Source/SourceKittenFramework/String+SourceKitten.swift b/Source/SourceKittenFramework/String+SourceKitten.swift index 432fd55be..5a4effe66 100644 --- a/Source/SourceKittenFramework/String+SourceKitten.swift +++ b/Source/SourceKittenFramework/String+SourceKitten.swift @@ -461,12 +461,12 @@ extension String { - parameter token: Token to process. */ public func isTokenDocumentable(token: SyntaxToken) -> Bool { - if token.type == SyntaxKind.keyword.rawValue { + if token.type == .keyword { let keywordFunctions = ["subscript", "init", "deinit"] return bridge().substringWithByteRange(start: token.offset, length: token.length) .map(keywordFunctions.contains) ?? false } - return token.type == SyntaxKind.identifier.rawValue + return token.type == .identifier } /** diff --git a/Source/SourceKittenFramework/Structure.swift b/Source/SourceKittenFramework/Structure.swift index ec9ded9c6..96ced1035 100644 --- a/Source/SourceKittenFramework/Structure.swift +++ b/Source/SourceKittenFramework/Structure.swift @@ -11,26 +11,36 @@ import Foundation /// Represents the structural information in a Swift source file. public struct Structure { /// Structural information as an [String: SourceKitRepresentable]. - public let dictionary: [String: SourceKitRepresentable] + public var dictionary: NSDictionary { + var dictionary = variant.any as! [String:Any] + dictionary.removeValue(forKey: UID.Key.syntaxmap.description) + return dictionary.bridge() + } + /// + public let variant: SourceKitVariant /** Create a Structure from a SourceKit `editor.open` response. - parameter sourceKitResponse: SourceKit `editor.open` response. */ - public init(sourceKitResponse: [String: SourceKitRepresentable]) { - var sourceKitResponse = sourceKitResponse - _ = sourceKitResponse.removeValue(forKey: SwiftDocKey.syntaxMap.rawValue) - dictionary = sourceKitResponse + @available(*, unavailable, message: "use Structure.init(sourceKitVariant:)") + public init(sourceKitResponse: [String: Any]) { + fatalError() + } + + init(sourceKitVariant: SourceKitVariant) { + variant = sourceKitVariant } /** Initialize a Structure by passing in a File. - parameter file: File to parse for structural information. + - throws: Request.Error */ - public init(file: File) { - self.init(sourceKitResponse: Request.editorOpen(file: file).send()) + public init(file: File) throws { + self.init(sourceKitVariant: try Request.editorOpen(file: file).failableSend()) } } @@ -38,7 +48,7 @@ public struct Structure { extension Structure: CustomStringConvertible { /// A textual JSON representation of `Structure`. - public var description: String { return toJSON(toNSDictionary(dictionary)) } + public var description: String { return toJSON(dictionary) } } // MARK: Equatable @@ -54,5 +64,5 @@ Returns true if `lhs` Structure is equal to `rhs` Structure. - returns: True if `lhs` Structure is equal to `rhs` Structure. */ public func == (lhs: Structure, rhs: Structure) -> Bool { - return lhs.dictionary.isEqualTo(rhs.dictionary) + return lhs.variant == rhs.variant } diff --git a/Source/SourceKittenFramework/SwiftDocKey.swift b/Source/SourceKittenFramework/SwiftDocKey.swift index 5505f6724..7d33c0192 100644 --- a/Source/SourceKittenFramework/SwiftDocKey.swift +++ b/Source/SourceKittenFramework/SwiftDocKey.swift @@ -96,7 +96,7 @@ public enum SwiftDocKey: String { - returns: Typed value of a dictionary key. */ - private static func get(_ key: SwiftDocKey, _ dictionary: [String: SourceKitRepresentable]) -> T? { + private static func get(_ key: SwiftDocKey, _ dictionary: [String: Any]) -> T? { return dictionary[key.rawValue] as! T? } @@ -107,7 +107,7 @@ public enum SwiftDocKey: String { - returns: Kind string if successful. */ - internal static func getKind(_ dictionary: [String: SourceKitRepresentable]) -> String? { + internal static func getKind(_ dictionary: [String: Any]) -> String? { return get(.kind, dictionary) } @@ -118,7 +118,7 @@ public enum SwiftDocKey: String { - returns: Syntax map data if successful. */ - internal static func getSyntaxMap(_ dictionary: [String: SourceKitRepresentable]) -> [SourceKitRepresentable]? { + internal static func getSyntaxMap(_ dictionary: [String: Any]) -> [Any]? { return get(.syntaxMap, dictionary) } @@ -129,7 +129,7 @@ public enum SwiftDocKey: String { - returns: Offset int if successful. */ - internal static func getOffset(_ dictionary: [String: SourceKitRepresentable]) -> Int64? { + internal static func getOffset(_ dictionary: [String: Any]) -> Int64? { return get(.offset, dictionary) } @@ -140,7 +140,7 @@ public enum SwiftDocKey: String { - returns: Length int if successful. */ - internal static func getLength(_ dictionary: [String: SourceKitRepresentable]) -> Int64? { + internal static func getLength(_ dictionary: [String: Any]) -> Int64? { return get(.length, dictionary) } @@ -151,7 +151,7 @@ public enum SwiftDocKey: String { - returns: Type name string if successful. */ - internal static func getTypeName(_ dictionary: [String: SourceKitRepresentable]) -> String? { + internal static func getTypeName(_ dictionary: [String: Any]) -> String? { return get(.typeName, dictionary) } @@ -162,7 +162,7 @@ public enum SwiftDocKey: String { - returns: Annotated declaration string if successful. */ - internal static func getAnnotatedDeclaration(_ dictionary: [String: SourceKitRepresentable]) -> String? { + internal static func getAnnotatedDeclaration(_ dictionary: [String: Any]) -> String? { return get(.annotatedDeclaration, dictionary) } @@ -173,7 +173,7 @@ public enum SwiftDocKey: String { - returns: Substructure array if successful. */ - internal static func getSubstructure(_ dictionary: [String: SourceKitRepresentable]) -> [SourceKitRepresentable]? { + internal static func getSubstructure(_ dictionary: [String: Any]) -> [Any]? { return get(.substructure, dictionary) } @@ -184,7 +184,7 @@ public enum SwiftDocKey: String { - returns: Name offset int if successful. */ - internal static func getNameOffset(_ dictionary: [String: SourceKitRepresentable]) -> Int64? { + internal static func getNameOffset(_ dictionary: [String: Any]) -> Int64? { return get(.nameOffset, dictionary) } @@ -195,7 +195,7 @@ public enum SwiftDocKey: String { - returns: Length int if successful. */ - internal static func getNameLength(_ dictionary: [String: SourceKitRepresentable]) -> Int64? { + internal static func getNameLength(_ dictionary: [String: Any]) -> Int64? { return get(.nameLength, dictionary) } @@ -206,7 +206,7 @@ public enum SwiftDocKey: String { - returns: Body offset int if successful. */ - internal static func getBodyOffset(_ dictionary: [String: SourceKitRepresentable]) -> Int64? { + internal static func getBodyOffset(_ dictionary: [String: Any]) -> Int64? { return get(.bodyOffset, dictionary) } @@ -217,7 +217,7 @@ public enum SwiftDocKey: String { - returns: Body length int if successful. */ - internal static func getBodyLength(_ dictionary: [String: SourceKitRepresentable]) -> Int64? { + internal static func getBodyLength(_ dictionary: [String: Any]) -> Int64? { return get(.bodyLength, dictionary) } @@ -228,7 +228,7 @@ public enum SwiftDocKey: String { - returns: File path string if successful. */ - internal static func getFilePath(_ dictionary: [String: SourceKitRepresentable]) -> String? { + internal static func getFilePath(_ dictionary: [String: Any]) -> String? { return get(.filePath, dictionary) } @@ -239,7 +239,7 @@ public enum SwiftDocKey: String { - returns: Full xml docs string if successful. */ - internal static func getFullXMLDocs(_ dictionary: [String: SourceKitRepresentable]) -> String? { + internal static func getFullXMLDocs(_ dictionary: [String: Any]) -> String? { return get(.fullXMLDocs, dictionary) } } diff --git a/Source/SourceKittenFramework/SwiftDocs.swift b/Source/SourceKittenFramework/SwiftDocs.swift index cca5c0f05..a9cb9cf2b 100644 --- a/Source/SourceKittenFramework/SwiftDocs.swift +++ b/Source/SourceKittenFramework/SwiftDocs.swift @@ -16,8 +16,8 @@ public struct SwiftDocs { /// Documented File. public let file: File - /// Docs information as an [String: SourceKitRepresentable]. - public let docsDictionary: [String: SourceKitRepresentable] + /// Docs information as an [String: Any]. + public let docsDictionary: [String: Any] /** Create docs for the specified Swift file and compiler arguments. @@ -29,7 +29,7 @@ public struct SwiftDocs { do { self.init( file: file, - dictionary: try Request.editorOpen(file: file).failableSend(), + sourceKitVariant: try Request.editorOpen(file: file).failableSend(), cursorInfoRequest: Request.cursorInfoRequest(filePath: file.path, arguments: arguments) ) } catch let error as Request.Error { @@ -47,21 +47,27 @@ public struct SwiftDocs { - parameter dictionary: editor.open response from SourceKit. - parameter cursorInfoRequest: SourceKit dictionary to use to send cursorinfo request. */ - public init(file: File, dictionary: [String: SourceKitRepresentable], cursorInfoRequest: sourcekitd_object_t?) { + @available(*, unavailable, message: "Use SwiftDocs.init(file:sourceKitVariant:cursorInfoRequest:)") + public init(file: File, dictionary: [String: Any], cursorInfoRequest: SourceKitObject?) { + fatalError() + } + + init(file: File, sourceKitVariant: SourceKitVariant, cursorInfoRequest: SourceKitObject?) { self.file = file - var dictionary = dictionary - let syntaxMapData = dictionary.removeValue(forKey: SwiftDocKey.syntaxMap.rawValue) as! [SourceKitRepresentable] - let syntaxMap = SyntaxMap(data: syntaxMapData) - dictionary = file.process(dictionary: dictionary, cursorInfoRequest: cursorInfoRequest, syntaxMap: syntaxMap) + var sourceKitVariant = sourceKitVariant + let syntaxMap = SyntaxMap(sourceKitVariant: sourceKitVariant) + sourceKitVariant = file.process(dictionary: sourceKitVariant, cursorInfoRequest: cursorInfoRequest, syntaxMap: syntaxMap) if let cursorInfoRequest = cursorInfoRequest { let documentedTokenOffsets = file.contents.documentedTokenOffsets(syntaxMap: syntaxMap) - dictionary = file.furtherProcess( - dictionary: dictionary, + sourceKitVariant = file.furtherProcess( + dictionary: sourceKitVariant, documentedTokenOffsets: documentedTokenOffsets, cursorInfoRequest: cursorInfoRequest, syntaxMap: syntaxMap ) } + var dictionary = sourceKitVariant.any as! [String:Any] + _ = dictionary.removeValue(forKey: UID.Key.syntaxmap.description) docsDictionary = dictionary } } @@ -71,6 +77,6 @@ public struct SwiftDocs { extension SwiftDocs: CustomStringConvertible { /// A textual JSON representation of `SwiftDocs`. public var description: String { - return toJSON(toNSDictionary([file.path ?? "": docsDictionary])) + return toJSON([file.path ?? "": docsDictionary]) } } diff --git a/Source/SourceKittenFramework/SyntaxMap.swift b/Source/SourceKittenFramework/SyntaxMap.swift index bf0bdff5d..6e0f3b73e 100644 --- a/Source/SourceKittenFramework/SyntaxMap.swift +++ b/Source/SourceKittenFramework/SyntaxMap.swift @@ -27,11 +27,9 @@ public struct SyntaxMap { - parameter data: NSData from a SourceKit `editor.open` response */ - public init(data: [SourceKitRepresentable]) { - tokens = data.map { item in - let dict = item as! [String: SourceKitRepresentable] - return SyntaxToken(type: dict["key.kind"] as! String, offset: Int(dict["key.offset"] as! Int64), length: Int(dict["key.length"] as! Int64)) - } + @available(*, unavailable, message: "Use SyntaxMap.init(sourceKitVariant:)") + public init(data: [Any]) { + fatalError() } /** @@ -39,17 +37,23 @@ public struct SyntaxMap { - parameter sourceKitResponse: SourceKit `editor.open` response. */ - public init(sourceKitResponse: [String: SourceKitRepresentable]) { - self.init(data: SwiftDocKey.getSyntaxMap(sourceKitResponse)!) + @available(*, unavailable, message: "use SyntaxMap.init(sourceKitVariant:)") + public init(sourceKitResponse: [String: Any]) { + fatalError() } /** Create a SyntaxMap from a File to be parsed. - parameter file: File to be parsed. + - throws: Request.Error */ - public init(file: File) { - self.init(sourceKitResponse: Request.editorOpen(file: file).send()) + public init(file: File) throws { + self.init(sourceKitVariant: try Request.editorOpen(file: file).failableSend()) + } + + init(sourceKitVariant: SourceKitVariant) { + self.init(tokens: sourceKitVariant.syntaxMap?.flatMap(SyntaxToken.init) ?? []) } /** @@ -62,7 +66,9 @@ public struct SyntaxMap { public func commentRange(beforeOffset offset: Int) -> Range? { let tokensBeforeOffset = tokens.reversed().filter { $0.offset < offset } - let docTypes = SyntaxKind.docComments().map({ $0.rawValue }) + let docTypes: [UID.SourceLangSwiftSyntaxtype] = [ + .commentUrl, .doccomment, .doccommentField + ] let isDoc = { (token: SyntaxToken) in docTypes.contains(token.type) } let isNotDoc = { !isDoc($0) } @@ -78,7 +84,7 @@ public struct SyntaxMap { return commentTokensImmediatelyPrecedingOffset.first.flatMap { firstToken in return commentTokensImmediatelyPrecedingOffset.last.flatMap { lastToken in let regularCommentTokensBetweenDocCommentAndOffset = tokensBeforeOffset - .filter({ $0.offset > lastToken.offset && SyntaxKind(rawValue: $0.type) == .comment }) + .filter({ $0.offset > lastToken.offset && $0.type == .comment }) if !regularCommentTokensBetweenDocCommentAndOffset.isEmpty { return nil // "doc comment" isn't actually a doc comment } diff --git a/Source/SourceKittenFramework/SyntaxToken.swift b/Source/SourceKittenFramework/SyntaxToken.swift index 38b042b80..bb314f042 100644 --- a/Source/SourceKittenFramework/SyntaxToken.swift +++ b/Source/SourceKittenFramework/SyntaxToken.swift @@ -9,7 +9,7 @@ /// Represents a single Swift syntax token. public struct SyntaxToken { /// Token type. See SyntaxKind. - public let type: String + public let type: UID.SourceLangSwiftSyntaxtype /// Token offset. public let offset: Int /// Token length. @@ -17,21 +17,30 @@ public struct SyntaxToken { /// Dictionary representation of SyntaxToken. Useful for NSJSONSerialization. public var dictionaryValue: [String: Any] { - return ["type": type, "offset": offset, "length": length] + return ["type": type.description, "offset": offset, "length": length] } /** Create a SyntaxToken by directly passing in its property values. - - parameter type: Token type. See SyntaxKind. + - parameter type: Token type. See UID.SourceLangSwiftSyntaxtype. - parameter offset: Token offset. - parameter length: Token length. */ - public init(type: String, offset: Int, length: Int) { - self.type = SyntaxKind(rawValue: type)?.rawValue ?? type + public init(type: UID.SourceLangSwiftSyntaxtype, offset: Int, length: Int) { + self.type = type self.offset = offset self.length = length } + + init?(sourceKitVariant: SourceKitVariant) { + guard let type = sourceKitVariant.kind.map(UID.SourceLangSwiftSyntaxtype.init), + let offset = sourceKitVariant.offset, + let length = sourceKitVariant.length else { + return nil + } + self.init(type: type, offset: offset, length: length) + } } // MARK: Equatable diff --git a/Source/SourceKittenFramework/UID.swift b/Source/SourceKittenFramework/UID.swift new file mode 100644 index 000000000..74417ae56 --- /dev/null +++ b/Source/SourceKittenFramework/UID.swift @@ -0,0 +1,116 @@ +// +// UID.swift +// SourceKitten +// +// Created by Norio Nomura on 10/21/16. +// Copyright © 2016 SourceKitten. All rights reserved. +// + +import Foundation +#if SWIFT_PACKAGE + import SourceKit +#endif + +/// Swift representation of sourcekitd_uid_t +public struct UID { + let uid: sourcekitd_uid_t + init(_ uid: sourcekitd_uid_t, _ string: String? = nil) { + self.uid = uid + _string = string + } + + fileprivate let _string: String? + var string: String { + if let _string = _string ?? knownSourceKitUIDStringMap[uid] { + return _string + } + let bytes = sourcekitd_uid_get_string_ptr(uid) + let length = sourcekitd_uid_get_length(uid) + return String(bytes: bytes!, length: length)! + } +} + +// MARK: - CustomStringConvertible +extension UID: CustomStringConvertible { + public var description: String { + return string + } +} + +// MARK: - ExpressibleByStringLiteral +extension UID: ExpressibleByStringLiteral { + public init(stringLiteral value: String) { + if let knownUID = knownUIDStringUIDMap[value] { + self.init(knownUID, value) + } else { + self.init(value) + #if DEBUG + preconditionFailure("\"\(value)\" is not predefined UID string!") + #endif + } + } + + public init(extendedGraphemeClusterLiteral value: String) { + if let knownUID = knownUIDStringUIDMap[value] { + self.init(knownUID, value) + } else { + self.init(value) + #if DEBUG + preconditionFailure("\"\(value)\" is not predefined UID string!") + #endif + } + } + + public init(unicodeScalarLiteral value: String) { + if let knownUID = knownUIDStringUIDMap[value] { + self.init(knownUID, value) + } else { + self.init(value) + #if DEBUG + preconditionFailure("\"\(value)\" is not predefined UID string!") + #endif + } + } + + init(_ string: String) { + uid = sourcekitd_uid_get_from_cstr(string) + _string = string + } +} + +// MARK: - Hashable +extension UID: Hashable { + public var hashValue: Int { + return uid.hashValue + } + + public static func == (lhs: UID, rhs: UID) -> Bool { + return lhs.uid == rhs.uid + } +} + +// MARK: - SourceKitObjectConvertible +extension UID: SourceKitObjectConvertible { + public var object: sourcekitd_object_t? { + return sourcekitd_request_uid_create(uid) + } +} + +// MARK: - Known UID caches +fileprivate let countOfKnownUIDs = knownUIDsSets.reduce(0, { $0 + $1.count }) + +/// SourceKit UID to String map. +fileprivate let knownSourceKitUIDStringMap: [sourcekitd_uid_t:String] = knownUIDsSets + .reduce(Dictionary(minimumCapacity: countOfKnownUIDs), { dictionary, set in + var dictionary = dictionary + set.forEach { dictionary[$0.uid] = $0._string } + return dictionary + }) + +/// String to SourceKit UID map. +fileprivate let knownUIDStringUIDMap: [String:sourcekitd_uid_t] = knownUIDsSets + .reduce(Dictionary(minimumCapacity: countOfKnownUIDs), { dictionary, set in + var dictionary = dictionary + set.forEach { dictionary[$0._string!] = $0.uid } + return dictionary + }) diff --git a/Source/SourceKittenFramework/UIDNamespace+generated.swift b/Source/SourceKittenFramework/UIDNamespace+generated.swift new file mode 100644 index 000000000..28b57c917 --- /dev/null +++ b/Source/SourceKittenFramework/UIDNamespace+generated.swift @@ -0,0 +1,1793 @@ +extension UID { + public struct Key { + public let uid: UID + /// key.accessibility + public static let accessibility: Key = "key.accessibility" + /// key.actionable + public static let actionable: Key = "key.actionable" + /// key.actionname + public static let actionname: Key = "key.actionname" + /// key.annotated_decl + public static let annotated_decl: Key = "key.annotated_decl" + /// key.annotations + public static let annotations: Key = "key.annotations" + /// key.associated_usrs + public static let associated_usrs: Key = "key.associated_usrs" + /// key.attribute + public static let attribute: Key = "key.attribute" + /// key.attributes + public static let attributes: Key = "key.attributes" + /// key.bodylength + public static let bodylength: Key = "key.bodylength" + /// key.bodyoffset + public static let bodyoffset: Key = "key.bodyoffset" + /// key.codecomplete.addinitstotoplevel + public static let codecompleteAddinitstotoplevel: Key = "key.codecomplete.addinitstotoplevel" + /// key.codecomplete.addinneroperators + public static let codecompleteAddinneroperators: Key = "key.codecomplete.addinneroperators" + /// key.codecomplete.addinnerresults + public static let codecompleteAddinnerresults: Key = "key.codecomplete.addinnerresults" + /// key.codecomplete.filterrules + public static let codecompleteFilterrules: Key = "key.codecomplete.filterrules" + /// key.codecomplete.filtertext + public static let codecompleteFiltertext: Key = "key.codecomplete.filtertext" + /// key.codecomplete.fuzzymatching + public static let codecompleteFuzzymatching: Key = "key.codecomplete.fuzzymatching" + /// key.codecomplete.group.overloads + public static let codecompleteGroupOverloads: Key = "key.codecomplete.group.overloads" + /// key.codecomplete.group.stems + public static let codecompleteGroupStems: Key = "key.codecomplete.group.stems" + /// key.codecomplete.hidebyname + public static let codecompleteHidebyname: Key = "key.codecomplete.hidebyname" + /// key.codecomplete.hidelowpriority + public static let codecompleteHidelowpriority: Key = "key.codecomplete.hidelowpriority" + /// key.codecomplete.hideunderscores + public static let codecompleteHideunderscores: Key = "key.codecomplete.hideunderscores" + /// key.codecomplete.includeexactmatch + public static let codecompleteIncludeexactmatch: Key = "key.codecomplete.includeexactmatch" + /// key.codecomplete.options + public static let codecompleteOptions: Key = "key.codecomplete.options" + /// key.codecomplete.requestlimit + public static let codecompleteRequestlimit: Key = "key.codecomplete.requestlimit" + /// key.codecomplete.requeststart + public static let codecompleteRequeststart: Key = "key.codecomplete.requeststart" + /// key.codecomplete.showtopnonliteralresults + public static let codecompleteShowtopnonliteralresults: Key = "key.codecomplete.showtopnonliteralresults" + /// key.codecomplete.sort.byname + public static let codecompleteSortByname: Key = "key.codecomplete.sort.byname" + /// key.codecomplete.sort.contextweight + public static let codecompleteSortContextweight: Key = "key.codecomplete.sort.contextweight" + /// key.codecomplete.sort.fuzzyweight + public static let codecompleteSortFuzzyweight: Key = "key.codecomplete.sort.fuzzyweight" + /// key.codecomplete.sort.popularitybonus + public static let codecompleteSortPopularitybonus: Key = "key.codecomplete.sort.popularitybonus" + /// key.codecomplete.sort.useimportdepth + public static let codecompleteSortUseimportdepth: Key = "key.codecomplete.sort.useimportdepth" + /// key.column + public static let column: Key = "key.column" + /// key.compilerargs + public static let compilerargs: Key = "key.compilerargs" + /// key.conforms + public static let conforms: Key = "key.conforms" + /// key.containertypeusr + public static let containertypeusr: Key = "key.containertypeusr" + /// key.context + public static let context: Key = "key.context" + /// key.default_implementation_of + public static let default_implementation_of: Key = "key.default_implementation_of" + /// key.dependencies + public static let dependencies: Key = "key.dependencies" + /// key.deprecated + public static let deprecated: Key = "key.deprecated" + /// key.description + public static let description: Key = "key.description" + /// key.diagnostic_stage + public static let diagnostic_stage: Key = "key.diagnostic_stage" + /// key.diagnostics + public static let diagnostics: Key = "key.diagnostics" + /// key.doc.brief + public static let docBrief: Key = "key.doc.brief" + /// key.doc.full_as_xml + public static let docFull_As_Xml: Key = "key.doc.full_as_xml" + /// key.duration + public static let duration: Key = "key.duration" + /// key.editor.format.indentwidth + public static let editorFormatIndentwidth: Key = "key.editor.format.indentwidth" + /// key.editor.format.options + public static let editorFormatOptions: Key = "key.editor.format.options" + /// key.editor.format.tabwidth + public static let editorFormatTabwidth: Key = "key.editor.format.tabwidth" + /// key.editor.format.usetabs + public static let editorFormatUsetabs: Key = "key.editor.format.usetabs" + /// key.elements + public static let elements: Key = "key.elements" + /// key.enablediagnostics + public static let enablediagnostics: Key = "key.enablediagnostics" + /// key.enablesubstructure + public static let enablesubstructure: Key = "key.enablesubstructure" + /// key.enablesyntaxmap + public static let enablesyntaxmap: Key = "key.enablesyntaxmap" + /// key.entities + public static let entities: Key = "key.entities" + /// key.extends + public static let extends: Key = "key.extends" + /// key.filepath + public static let filepath: Key = "key.filepath" + /// key.fixits + public static let fixits: Key = "key.fixits" + /// key.fully_annotated_decl + public static let fully_annotated_decl: Key = "key.fully_annotated_decl" + /// key.generic_params + public static let generic_params: Key = "key.generic_params" + /// key.generic_requirements + public static let generic_requirements: Key = "key.generic_requirements" + /// key.groupname + public static let groupname: Key = "key.groupname" + /// key.hash + public static let hash: Key = "key.hash" + /// key.hide + public static let hide: Key = "key.hide" + /// key.inheritedtypes + public static let inheritedtypes: Key = "key.inheritedtypes" + /// key.inherits + public static let inherits: Key = "key.inherits" + /// key.interested_usr + public static let interested_usr: Key = "key.interested_usr" + /// key.introduced + public static let introduced: Key = "key.introduced" + /// key.is_deprecated + public static let is_deprecated: Key = "key.is_deprecated" + /// key.is_dynamic + public static let is_dynamic: Key = "key.is_dynamic" + /// key.is_local + public static let is_local: Key = "key.is_local" + /// key.is_optional + public static let is_optional: Key = "key.is_optional" + /// key.is_system + public static let is_system: Key = "key.is_system" + /// key.is_test_candidate + public static let is_test_candidate: Key = "key.is_test_candidate" + /// key.is_unavailable + public static let is_unavailable: Key = "key.is_unavailable" + /// key.keyword + public static let keyword: Key = "key.keyword" + /// key.kind + public static let kind: Key = "key.kind" + /// key.length + public static let length: Key = "key.length" + /// key.line + public static let line: Key = "key.line" + /// key.message + public static let message: Key = "key.message" + /// key.module_interface_name + public static let module_interface_name: Key = "key.module_interface_name" + /// key.modulegroups + public static let modulegroups: Key = "key.modulegroups" + /// key.moduleimportdepth + public static let moduleimportdepth: Key = "key.moduleimportdepth" + /// key.modulename + public static let modulename: Key = "key.modulename" + /// key.name + public static let name: Key = "key.name" + /// key.namelength + public static let namelength: Key = "key.namelength" + /// key.nameoffset + public static let nameoffset: Key = "key.nameoffset" + /// key.names + public static let names: Key = "key.names" + /// key.nextrequeststart + public static let nextrequeststart: Key = "key.nextrequeststart" + /// key.not_recommended + public static let not_recommended: Key = "key.not_recommended" + /// key.notification + public static let notification: Key = "key.notification" + /// key.num_bytes_to_erase + public static let num_bytes_to_erase: Key = "key.num_bytes_to_erase" + /// key.obsoleted + public static let obsoleted: Key = "key.obsoleted" + /// key.offset + public static let offset: Key = "key.offset" + /// key.original_usr + public static let original_usr: Key = "key.original_usr" + /// key.overrides + public static let overrides: Key = "key.overrides" + /// key.platform + public static let platform: Key = "key.platform" + /// key.popular + public static let popular: Key = "key.popular" + /// key.rangecontent + public static let rangecontent: Key = "key.rangecontent" + /// key.ranges + public static let ranges: Key = "key.ranges" + /// key.receiver_usr + public static let receiver_usr: Key = "key.receiver_usr" + /// key.related + public static let related: Key = "key.related" + /// key.related_decls + public static let related_decls: Key = "key.related_decls" + /// key.removecache + public static let removecache: Key = "key.removecache" + /// key.request + public static let request: Key = "key.request" + /// key.results + public static let results: Key = "key.results" + /// key.runtime_name + public static let runtime_name: Key = "key.runtime_name" + /// key.selector_name + public static let selector_name: Key = "key.selector_name" + /// key.setter_accessibility + public static let setter_accessibility: Key = "key.setter_accessibility" + /// key.severity + public static let severity: Key = "key.severity" + /// key.simplified + public static let simplified: Key = "key.simplified" + /// key.sourcefile + public static let sourcefile: Key = "key.sourcefile" + /// key.sourcetext + public static let sourcetext: Key = "key.sourcetext" + /// key.substructure + public static let substructure: Key = "key.substructure" + /// key.syntactic_only + public static let syntactic_only: Key = "key.syntactic_only" + /// key.syntaxmap + public static let syntaxmap: Key = "key.syntaxmap" + /// key.synthesizedextensions + public static let synthesizedextensions: Key = "key.synthesizedextensions" + /// key.throwlength + public static let throwlength: Key = "key.throwlength" + /// key.throwoffset + public static let throwoffset: Key = "key.throwoffset" + /// key.typeinterface + public static let typeinterface: Key = "key.typeinterface" + /// key.typename + public static let typename: Key = "key.typename" + /// key.typeusr + public static let typeusr: Key = "key.typeusr" + /// key.uids + public static let uids: Key = "key.uids" + /// key.unpopular + public static let unpopular: Key = "key.unpopular" + /// key.usr + public static let usr: Key = "key.usr" + /// key.version_major + public static let version_major: Key = "key.version_major" + /// key.version_minor + public static let version_minor: Key = "key.version_minor" + } + public struct SourceAvailabilityPlatform { + public let uid: UID + /// source.availability.platform.ios + public static let ios: SourceAvailabilityPlatform = "source.availability.platform.ios" + /// source.availability.platform.ios_app_extension + public static let ios_app_extension: SourceAvailabilityPlatform = "source.availability.platform.ios_app_extension" + /// source.availability.platform.osx + public static let osx: SourceAvailabilityPlatform = "source.availability.platform.osx" + /// source.availability.platform.osx_app_extension + public static let osx_app_extension: SourceAvailabilityPlatform = "source.availability.platform.osx_app_extension" + /// source.availability.platform.tvos + public static let tvos: SourceAvailabilityPlatform = "source.availability.platform.tvos" + /// source.availability.platform.tvos_app_extension + public static let tvos_app_extension: SourceAvailabilityPlatform = "source.availability.platform.tvos_app_extension" + /// source.availability.platform.watchos + public static let watchos: SourceAvailabilityPlatform = "source.availability.platform.watchos" + /// source.availability.platform.watchos_app_extension + public static let watchos_app_extension: SourceAvailabilityPlatform = "source.availability.platform.watchos_app_extension" + } + public struct SourceCodecompletion { + public let uid: UID + /// source.codecompletion.context.exprspecific + public static let contextExprspecific: SourceCodecompletion = "source.codecompletion.context.exprspecific" + /// source.codecompletion.context.local + public static let contextLocal: SourceCodecompletion = "source.codecompletion.context.local" + /// source.codecompletion.context.none + public static let contextNone: SourceCodecompletion = "source.codecompletion.context.none" + /// source.codecompletion.context.otherclass + public static let contextOtherclass: SourceCodecompletion = "source.codecompletion.context.otherclass" + /// source.codecompletion.context.othermodule + public static let contextOthermodule: SourceCodecompletion = "source.codecompletion.context.othermodule" + /// source.codecompletion.context.superclass + public static let contextSuperclass: SourceCodecompletion = "source.codecompletion.context.superclass" + /// source.codecompletion.context.thisclass + public static let contextThisclass: SourceCodecompletion = "source.codecompletion.context.thisclass" + /// source.codecompletion.context.thismodule + public static let contextThismodule: SourceCodecompletion = "source.codecompletion.context.thismodule" + /// source.codecompletion.custom + public static let custom: SourceCodecompletion = "source.codecompletion.custom" + /// source.codecompletion.everything + public static let everything: SourceCodecompletion = "source.codecompletion.everything" + /// source.codecompletion.identifier + public static let identifier: SourceCodecompletion = "source.codecompletion.identifier" + /// source.codecompletion.keyword + public static let keyword: SourceCodecompletion = "source.codecompletion.keyword" + /// source.codecompletion.literal + public static let literal: SourceCodecompletion = "source.codecompletion.literal" + /// source.codecompletion.module + public static let module: SourceCodecompletion = "source.codecompletion.module" + } + public struct SourceDeclAttribute { + public let uid: UID + /// source.decl.attribute.LLDBDebuggerFunction + public static let LLDBDebuggerFunction: SourceDeclAttribute = "source.decl.attribute.LLDBDebuggerFunction" + /// source.decl.attribute.NSApplicationMain + public static let NSApplicationMain: SourceDeclAttribute = "source.decl.attribute.NSApplicationMain" + /// source.decl.attribute.NSCopying + public static let NSCopying: SourceDeclAttribute = "source.decl.attribute.NSCopying" + /// source.decl.attribute.NSManaged + public static let NSManaged: SourceDeclAttribute = "source.decl.attribute.NSManaged" + /// source.decl.attribute.UIApplicationMain + public static let UIApplicationMain: SourceDeclAttribute = "source.decl.attribute.UIApplicationMain" + /// source.decl.attribute.__objc_bridged + public static let __objc_bridged: SourceDeclAttribute = "source.decl.attribute.__objc_bridged" + /// source.decl.attribute.__synthesized_protocol + public static let __synthesized_protocol: SourceDeclAttribute = "source.decl.attribute.__synthesized_protocol" + /// source.decl.attribute._alignment + public static let _alignment: SourceDeclAttribute = "source.decl.attribute._alignment" + /// source.decl.attribute._cdecl + public static let _cdecl: SourceDeclAttribute = "source.decl.attribute._cdecl" + /// source.decl.attribute._exported + public static let _exported: SourceDeclAttribute = "source.decl.attribute._exported" + /// source.decl.attribute._fixed_layout + public static let _fixed_layout: SourceDeclAttribute = "source.decl.attribute._fixed_layout" + /// source.decl.attribute._inlineable + public static let _inlineable: SourceDeclAttribute = "source.decl.attribute._inlineable" + /// source.decl.attribute._semantics + public static let _semantics: SourceDeclAttribute = "source.decl.attribute._semantics" + /// source.decl.attribute._silgen_name + public static let _silgen_name: SourceDeclAttribute = "source.decl.attribute._silgen_name" + /// source.decl.attribute._specialize + public static let _specialize: SourceDeclAttribute = "source.decl.attribute._specialize" + /// source.decl.attribute._swift_native_objc_runtime_base + public static let _swift_native_objc_runtime_base: SourceDeclAttribute = "source.decl.attribute._swift_native_objc_runtime_base" + /// source.decl.attribute._transparent + public static let _transparent: SourceDeclAttribute = "source.decl.attribute._transparent" + /// source.decl.attribute._versioned + public static let _versioned: SourceDeclAttribute = "source.decl.attribute._versioned" + /// source.decl.attribute.autoclosure + public static let autoclosure: SourceDeclAttribute = "source.decl.attribute.autoclosure" + /// source.decl.attribute.available + public static let available: SourceDeclAttribute = "source.decl.attribute.available" + /// source.decl.attribute.convenience + public static let convenience: SourceDeclAttribute = "source.decl.attribute.convenience" + /// source.decl.attribute.discardableResult + public static let discardableResult: SourceDeclAttribute = "source.decl.attribute.discardableResult" + /// source.decl.attribute.dynamic + public static let dynamic: SourceDeclAttribute = "source.decl.attribute.dynamic" + /// source.decl.attribute.effects + public static let effects: SourceDeclAttribute = "source.decl.attribute.effects" + /// source.decl.attribute.final + public static let final: SourceDeclAttribute = "source.decl.attribute.final" + /// source.decl.attribute.gkinspectable + public static let gkinspectable: SourceDeclAttribute = "source.decl.attribute.gkinspectable" + /// source.decl.attribute.ibaction + public static let ibaction: SourceDeclAttribute = "source.decl.attribute.ibaction" + /// source.decl.attribute.ibdesignable + public static let ibdesignable: SourceDeclAttribute = "source.decl.attribute.ibdesignable" + /// source.decl.attribute.ibinspectable + public static let ibinspectable: SourceDeclAttribute = "source.decl.attribute.ibinspectable" + /// source.decl.attribute.iboutlet + public static let iboutlet: SourceDeclAttribute = "source.decl.attribute.iboutlet" + /// source.decl.attribute.indirect + public static let indirect: SourceDeclAttribute = "source.decl.attribute.indirect" + /// source.decl.attribute.infix + public static let infix: SourceDeclAttribute = "source.decl.attribute.infix" + /// source.decl.attribute.inline + public static let inline: SourceDeclAttribute = "source.decl.attribute.inline" + /// source.decl.attribute.lazy + public static let lazy: SourceDeclAttribute = "source.decl.attribute.lazy" + /// source.decl.attribute.mutating + public static let mutating: SourceDeclAttribute = "source.decl.attribute.mutating" + /// source.decl.attribute.noescape + public static let noescape: SourceDeclAttribute = "source.decl.attribute.noescape" + /// source.decl.attribute.nonmutating + public static let nonmutating: SourceDeclAttribute = "source.decl.attribute.nonmutating" + /// source.decl.attribute.nonobjc + public static let nonobjc: SourceDeclAttribute = "source.decl.attribute.nonobjc" + /// source.decl.attribute.noreturn + public static let noreturn: SourceDeclAttribute = "source.decl.attribute.noreturn" + /// source.decl.attribute.objc + public static let objc: SourceDeclAttribute = "source.decl.attribute.objc" + /// source.decl.attribute.objc.name + public static let objcName: SourceDeclAttribute = "source.decl.attribute.objc.name" + /// source.decl.attribute.objc_non_lazy_realization + public static let objc_non_lazy_realization: SourceDeclAttribute = "source.decl.attribute.objc_non_lazy_realization" + /// source.decl.attribute.optional + public static let optional: SourceDeclAttribute = "source.decl.attribute.optional" + /// source.decl.attribute.override + public static let override: SourceDeclAttribute = "source.decl.attribute.override" + /// source.decl.attribute.postfix + public static let postfix: SourceDeclAttribute = "source.decl.attribute.postfix" + /// source.decl.attribute.prefix + public static let prefix: SourceDeclAttribute = "source.decl.attribute.prefix" + /// source.decl.attribute.required + public static let required: SourceDeclAttribute = "source.decl.attribute.required" + /// source.decl.attribute.requires_stored_property_inits + public static let requires_stored_property_inits: SourceDeclAttribute = "source.decl.attribute.requires_stored_property_inits" + /// source.decl.attribute.rethrows + public static let `rethrows`: SourceDeclAttribute = "source.decl.attribute.rethrows" + /// source.decl.attribute.sil_stored + public static let sil_stored: SourceDeclAttribute = "source.decl.attribute.sil_stored" + /// source.decl.attribute.testable + public static let testable: SourceDeclAttribute = "source.decl.attribute.testable" + /// source.decl.attribute.unsafe_no_objc_tagged_pointer + public static let unsafe_no_objc_tagged_pointer: SourceDeclAttribute = "source.decl.attribute.unsafe_no_objc_tagged_pointer" + /// source.decl.attribute.warn_unqualified_access + public static let warn_unqualified_access: SourceDeclAttribute = "source.decl.attribute.warn_unqualified_access" + /// source.decl.attribute.weak + public static let weak: SourceDeclAttribute = "source.decl.attribute.weak" + } + public struct SourceDiagnosticSeverity { + public let uid: UID + /// source.diagnostic.severity.error + public static let error: SourceDiagnosticSeverity = "source.diagnostic.severity.error" + /// source.diagnostic.severity.note + public static let note: SourceDiagnosticSeverity = "source.diagnostic.severity.note" + /// source.diagnostic.severity.warning + public static let warning: SourceDiagnosticSeverity = "source.diagnostic.severity.warning" + } + public struct SourceDiagnosticStageSwift { + public let uid: UID + /// source.diagnostic.stage.swift.parse + public static let parse: SourceDiagnosticStageSwift = "source.diagnostic.stage.swift.parse" + /// source.diagnostic.stage.swift.sema + public static let sema: SourceDiagnosticStageSwift = "source.diagnostic.stage.swift.sema" + } + public struct SourceLangSwift { + public let uid: UID + /// source.lang.swift.expr + public static let expr: SourceLangSwift = "source.lang.swift.expr" + /// source.lang.swift.keyword + public static let keyword: SourceLangSwift = "source.lang.swift.keyword" + /// source.lang.swift.pattern + public static let pattern: SourceLangSwift = "source.lang.swift.pattern" + /// source.lang.swift.range.invalid + public static let rangeInvalid: SourceLangSwift = "source.lang.swift.range.invalid" + /// source.lang.swift.range.multistatement + public static let rangeMultistatement: SourceLangSwift = "source.lang.swift.range.multistatement" + /// source.lang.swift.range.singledeclaration + public static let rangeSingledeclaration: SourceLangSwift = "source.lang.swift.range.singledeclaration" + /// source.lang.swift.range.singleexpression + public static let rangeSingleexpression: SourceLangSwift = "source.lang.swift.range.singleexpression" + /// source.lang.swift.range.singlestatement + public static let rangeSinglestatement: SourceLangSwift = "source.lang.swift.range.singlestatement" + /// source.lang.swift.stmt + public static let stmt: SourceLangSwift = "source.lang.swift.stmt" + /// source.lang.swift.type + public static let type: SourceLangSwift = "source.lang.swift.type" + } + public struct SourceLangSwiftAccessibility { + public let uid: UID + /// source.lang.swift.accessibility.fileprivate + public static let `fileprivate`: SourceLangSwiftAccessibility = "source.lang.swift.accessibility.fileprivate" + /// source.lang.swift.accessibility.internal + public static let `internal`: SourceLangSwiftAccessibility = "source.lang.swift.accessibility.internal" + /// source.lang.swift.accessibility.open + public static let open: SourceLangSwiftAccessibility = "source.lang.swift.accessibility.open" + /// source.lang.swift.accessibility.private + public static let `private`: SourceLangSwiftAccessibility = "source.lang.swift.accessibility.private" + /// source.lang.swift.accessibility.public + public static let `public`: SourceLangSwiftAccessibility = "source.lang.swift.accessibility.public" + } + public struct SourceLangSwiftAttribute { + public let uid: UID + /// source.lang.swift.attribute.availability + public static let availability: SourceLangSwiftAttribute = "source.lang.swift.attribute.availability" + } + public struct SourceLangSwiftCodecomplete { + public let uid: UID + /// source.lang.swift.codecomplete.group + public static let group: SourceLangSwiftCodecomplete = "source.lang.swift.codecomplete.group" + } + public struct SourceLangSwiftDecl { + public let uid: UID + /// source.lang.swift.decl.associatedtype + public static let `associatedtype`: SourceLangSwiftDecl = "source.lang.swift.decl.associatedtype" + /// source.lang.swift.decl.class + public static let `class`: SourceLangSwiftDecl = "source.lang.swift.decl.class" + /// source.lang.swift.decl.enum + public static let `enum`: SourceLangSwiftDecl = "source.lang.swift.decl.enum" + /// source.lang.swift.decl.enumcase + public static let enumcase: SourceLangSwiftDecl = "source.lang.swift.decl.enumcase" + /// source.lang.swift.decl.enumelement + public static let enumelement: SourceLangSwiftDecl = "source.lang.swift.decl.enumelement" + /// source.lang.swift.decl.extension + public static let `extension`: SourceLangSwiftDecl = "source.lang.swift.decl.extension" + /// source.lang.swift.decl.extension.class + public static let extensionClass: SourceLangSwiftDecl = "source.lang.swift.decl.extension.class" + /// source.lang.swift.decl.extension.enum + public static let extensionEnum: SourceLangSwiftDecl = "source.lang.swift.decl.extension.enum" + /// source.lang.swift.decl.extension.protocol + public static let extensionProtocol: SourceLangSwiftDecl = "source.lang.swift.decl.extension.protocol" + /// source.lang.swift.decl.extension.struct + public static let extensionStruct: SourceLangSwiftDecl = "source.lang.swift.decl.extension.struct" + /// source.lang.swift.decl.function.accessor.address + public static let functionAccessorAddress: SourceLangSwiftDecl = "source.lang.swift.decl.function.accessor.address" + /// source.lang.swift.decl.function.accessor.didset + public static let functionAccessorDidset: SourceLangSwiftDecl = "source.lang.swift.decl.function.accessor.didset" + /// source.lang.swift.decl.function.accessor.getter + public static let functionAccessorGetter: SourceLangSwiftDecl = "source.lang.swift.decl.function.accessor.getter" + /// source.lang.swift.decl.function.accessor.mutableaddress + public static let functionAccessorMutableaddress: SourceLangSwiftDecl = "source.lang.swift.decl.function.accessor.mutableaddress" + /// source.lang.swift.decl.function.accessor.setter + public static let functionAccessorSetter: SourceLangSwiftDecl = "source.lang.swift.decl.function.accessor.setter" + /// source.lang.swift.decl.function.accessor.willset + public static let functionAccessorWillset: SourceLangSwiftDecl = "source.lang.swift.decl.function.accessor.willset" + /// source.lang.swift.decl.function.constructor + public static let functionConstructor: SourceLangSwiftDecl = "source.lang.swift.decl.function.constructor" + /// source.lang.swift.decl.function.destructor + public static let functionDestructor: SourceLangSwiftDecl = "source.lang.swift.decl.function.destructor" + /// source.lang.swift.decl.function.free + public static let functionFree: SourceLangSwiftDecl = "source.lang.swift.decl.function.free" + /// source.lang.swift.decl.function.method.class + public static let functionMethodClass: SourceLangSwiftDecl = "source.lang.swift.decl.function.method.class" + /// source.lang.swift.decl.function.method.instance + public static let functionMethodInstance: SourceLangSwiftDecl = "source.lang.swift.decl.function.method.instance" + /// source.lang.swift.decl.function.method.static + public static let functionMethodStatic: SourceLangSwiftDecl = "source.lang.swift.decl.function.method.static" + /// source.lang.swift.decl.function.operator.infix + public static let functionOperatorInfix: SourceLangSwiftDecl = "source.lang.swift.decl.function.operator.infix" + /// source.lang.swift.decl.function.operator.postfix + public static let functionOperatorPostfix: SourceLangSwiftDecl = "source.lang.swift.decl.function.operator.postfix" + /// source.lang.swift.decl.function.operator.prefix + public static let functionOperatorPrefix: SourceLangSwiftDecl = "source.lang.swift.decl.function.operator.prefix" + /// source.lang.swift.decl.function.subscript + public static let functionSubscript: SourceLangSwiftDecl = "source.lang.swift.decl.function.subscript" + /// source.lang.swift.decl.generic_type_param + public static let generic_type_param: SourceLangSwiftDecl = "source.lang.swift.decl.generic_type_param" + /// source.lang.swift.decl.module + public static let module: SourceLangSwiftDecl = "source.lang.swift.decl.module" + /// source.lang.swift.decl.precedencegroup + public static let `precedencegroup`: SourceLangSwiftDecl = "source.lang.swift.decl.precedencegroup" + /// source.lang.swift.decl.protocol + public static let `protocol`: SourceLangSwiftDecl = "source.lang.swift.decl.protocol" + /// source.lang.swift.decl.struct + public static let `struct`: SourceLangSwiftDecl = "source.lang.swift.decl.struct" + /// source.lang.swift.decl.typealias + public static let `typealias`: SourceLangSwiftDecl = "source.lang.swift.decl.typealias" + /// source.lang.swift.decl.var.class + public static let varClass: SourceLangSwiftDecl = "source.lang.swift.decl.var.class" + /// source.lang.swift.decl.var.global + public static let varGlobal: SourceLangSwiftDecl = "source.lang.swift.decl.var.global" + /// source.lang.swift.decl.var.instance + public static let varInstance: SourceLangSwiftDecl = "source.lang.swift.decl.var.instance" + /// source.lang.swift.decl.var.local + public static let varLocal: SourceLangSwiftDecl = "source.lang.swift.decl.var.local" + /// source.lang.swift.decl.var.parameter + public static let varParameter: SourceLangSwiftDecl = "source.lang.swift.decl.var.parameter" + /// source.lang.swift.decl.var.static + public static let varStatic: SourceLangSwiftDecl = "source.lang.swift.decl.var.static" + } + public struct SourceLangSwiftExpr { + public let uid: UID + /// source.lang.swift.expr.argument + public static let argument: SourceLangSwiftExpr = "source.lang.swift.expr.argument" + /// source.lang.swift.expr.array + public static let array: SourceLangSwiftExpr = "source.lang.swift.expr.array" + /// source.lang.swift.expr.call + public static let call: SourceLangSwiftExpr = "source.lang.swift.expr.call" + /// source.lang.swift.expr.dictionary + public static let dictionary: SourceLangSwiftExpr = "source.lang.swift.expr.dictionary" + /// source.lang.swift.expr.object_literal + public static let object_literal: SourceLangSwiftExpr = "source.lang.swift.expr.object_literal" + } + public struct SourceLangSwiftImportModule { + public let uid: UID + /// source.lang.swift.import.module.clang + public static let clang: SourceLangSwiftImportModule = "source.lang.swift.import.module.clang" + /// source.lang.swift.import.module.swift + public static let swift: SourceLangSwiftImportModule = "source.lang.swift.import.module.swift" + } + public struct SourceLangSwiftKeyword { + public let uid: UID + /// source.lang.swift.keyword.Any + public static let `Any`: SourceLangSwiftKeyword = "source.lang.swift.keyword.Any" + /// source.lang.swift.keyword.Self + public static let `Self`: SourceLangSwiftKeyword = "source.lang.swift.keyword.Self" + /// source.lang.swift.keyword._ + public static let `_`: SourceLangSwiftKeyword = "source.lang.swift.keyword._" + /// source.lang.swift.keyword.__COLUMN__ + public static let `__COLUMN__`: SourceLangSwiftKeyword = "source.lang.swift.keyword.__COLUMN__" + /// source.lang.swift.keyword.__DSO_HANDLE__ + public static let `__DSO_HANDLE__`: SourceLangSwiftKeyword = "source.lang.swift.keyword.__DSO_HANDLE__" + /// source.lang.swift.keyword.__FILE__ + public static let `__FILE__`: SourceLangSwiftKeyword = "source.lang.swift.keyword.__FILE__" + /// source.lang.swift.keyword.__FUNCTION__ + public static let `__FUNCTION__`: SourceLangSwiftKeyword = "source.lang.swift.keyword.__FUNCTION__" + /// source.lang.swift.keyword.__LINE__ + public static let `__LINE__`: SourceLangSwiftKeyword = "source.lang.swift.keyword.__LINE__" + /// source.lang.swift.keyword.as + public static let `as`: SourceLangSwiftKeyword = "source.lang.swift.keyword.as" + /// source.lang.swift.keyword.associatedtype + public static let `associatedtype`: SourceLangSwiftKeyword = "source.lang.swift.keyword.associatedtype" + /// source.lang.swift.keyword.break + public static let `break`: SourceLangSwiftKeyword = "source.lang.swift.keyword.break" + /// source.lang.swift.keyword.case + public static let `case`: SourceLangSwiftKeyword = "source.lang.swift.keyword.case" + /// source.lang.swift.keyword.catch + public static let `catch`: SourceLangSwiftKeyword = "source.lang.swift.keyword.catch" + /// source.lang.swift.keyword.class + public static let `class`: SourceLangSwiftKeyword = "source.lang.swift.keyword.class" + /// source.lang.swift.keyword.continue + public static let `continue`: SourceLangSwiftKeyword = "source.lang.swift.keyword.continue" + /// source.lang.swift.keyword.default + public static let `default`: SourceLangSwiftKeyword = "source.lang.swift.keyword.default" + /// source.lang.swift.keyword.defer + public static let `defer`: SourceLangSwiftKeyword = "source.lang.swift.keyword.defer" + /// source.lang.swift.keyword.deinit + public static let `deinit`: SourceLangSwiftKeyword = "source.lang.swift.keyword.deinit" + /// source.lang.swift.keyword.do + public static let `do`: SourceLangSwiftKeyword = "source.lang.swift.keyword.do" + /// source.lang.swift.keyword.else + public static let `else`: SourceLangSwiftKeyword = "source.lang.swift.keyword.else" + /// source.lang.swift.keyword.enum + public static let `enum`: SourceLangSwiftKeyword = "source.lang.swift.keyword.enum" + /// source.lang.swift.keyword.extension + public static let `extension`: SourceLangSwiftKeyword = "source.lang.swift.keyword.extension" + /// source.lang.swift.keyword.fallthrough + public static let `fallthrough`: SourceLangSwiftKeyword = "source.lang.swift.keyword.fallthrough" + /// source.lang.swift.keyword.false + public static let `false`: SourceLangSwiftKeyword = "source.lang.swift.keyword.false" + /// source.lang.swift.keyword.fileprivate + public static let `fileprivate`: SourceLangSwiftKeyword = "source.lang.swift.keyword.fileprivate" + /// source.lang.swift.keyword.for + public static let `for`: SourceLangSwiftKeyword = "source.lang.swift.keyword.for" + /// source.lang.swift.keyword.func + public static let `func`: SourceLangSwiftKeyword = "source.lang.swift.keyword.func" + /// source.lang.swift.keyword.guard + public static let `guard`: SourceLangSwiftKeyword = "source.lang.swift.keyword.guard" + /// source.lang.swift.keyword.if + public static let `if`: SourceLangSwiftKeyword = "source.lang.swift.keyword.if" + /// source.lang.swift.keyword.import + public static let `import`: SourceLangSwiftKeyword = "source.lang.swift.keyword.import" + /// source.lang.swift.keyword.in + public static let `in`: SourceLangSwiftKeyword = "source.lang.swift.keyword.in" + /// source.lang.swift.keyword.init + public static let `init`: SourceLangSwiftKeyword = "source.lang.swift.keyword.init" + /// source.lang.swift.keyword.inout + public static let `inout`: SourceLangSwiftKeyword = "source.lang.swift.keyword.inout" + /// source.lang.swift.keyword.internal + public static let `internal`: SourceLangSwiftKeyword = "source.lang.swift.keyword.internal" + /// source.lang.swift.keyword.is + public static let `is`: SourceLangSwiftKeyword = "source.lang.swift.keyword.is" + /// source.lang.swift.keyword.let + public static let `let`: SourceLangSwiftKeyword = "source.lang.swift.keyword.let" + /// source.lang.swift.keyword.nil + public static let `nil`: SourceLangSwiftKeyword = "source.lang.swift.keyword.nil" + /// source.lang.swift.keyword.operator + public static let `operator`: SourceLangSwiftKeyword = "source.lang.swift.keyword.operator" + /// source.lang.swift.keyword.precedencegroup + public static let `precedencegroup`: SourceLangSwiftKeyword = "source.lang.swift.keyword.precedencegroup" + /// source.lang.swift.keyword.private + public static let `private`: SourceLangSwiftKeyword = "source.lang.swift.keyword.private" + /// source.lang.swift.keyword.protocol + public static let `protocol`: SourceLangSwiftKeyword = "source.lang.swift.keyword.protocol" + /// source.lang.swift.keyword.public + public static let `public`: SourceLangSwiftKeyword = "source.lang.swift.keyword.public" + /// source.lang.swift.keyword.repeat + public static let `repeat`: SourceLangSwiftKeyword = "source.lang.swift.keyword.repeat" + /// source.lang.swift.keyword.rethrows + public static let `rethrows`: SourceLangSwiftKeyword = "source.lang.swift.keyword.rethrows" + /// source.lang.swift.keyword.return + public static let `return`: SourceLangSwiftKeyword = "source.lang.swift.keyword.return" + /// source.lang.swift.keyword.self + public static let `self`: SourceLangSwiftKeyword = "source.lang.swift.keyword.self" + /// source.lang.swift.keyword.static + public static let `static`: SourceLangSwiftKeyword = "source.lang.swift.keyword.static" + /// source.lang.swift.keyword.struct + public static let `struct`: SourceLangSwiftKeyword = "source.lang.swift.keyword.struct" + /// source.lang.swift.keyword.subscript + public static let `subscript`: SourceLangSwiftKeyword = "source.lang.swift.keyword.subscript" + /// source.lang.swift.keyword.super + public static let `super`: SourceLangSwiftKeyword = "source.lang.swift.keyword.super" + /// source.lang.swift.keyword.switch + public static let `switch`: SourceLangSwiftKeyword = "source.lang.swift.keyword.switch" + /// source.lang.swift.keyword.throw + public static let `throw`: SourceLangSwiftKeyword = "source.lang.swift.keyword.throw" + /// source.lang.swift.keyword.throws + public static let `throws`: SourceLangSwiftKeyword = "source.lang.swift.keyword.throws" + /// source.lang.swift.keyword.true + public static let `true`: SourceLangSwiftKeyword = "source.lang.swift.keyword.true" + /// source.lang.swift.keyword.try + public static let `try`: SourceLangSwiftKeyword = "source.lang.swift.keyword.try" + /// source.lang.swift.keyword.typealias + public static let `typealias`: SourceLangSwiftKeyword = "source.lang.swift.keyword.typealias" + /// source.lang.swift.keyword.var + public static let `var`: SourceLangSwiftKeyword = "source.lang.swift.keyword.var" + /// source.lang.swift.keyword.where + public static let `where`: SourceLangSwiftKeyword = "source.lang.swift.keyword.where" + /// source.lang.swift.keyword.while + public static let `while`: SourceLangSwiftKeyword = "source.lang.swift.keyword.while" + } + public struct SourceLangSwiftLiteral { + public let uid: UID + /// source.lang.swift.literal.array + public static let array: SourceLangSwiftLiteral = "source.lang.swift.literal.array" + /// source.lang.swift.literal.boolean + public static let boolean: SourceLangSwiftLiteral = "source.lang.swift.literal.boolean" + /// source.lang.swift.literal.color + public static let color: SourceLangSwiftLiteral = "source.lang.swift.literal.color" + /// source.lang.swift.literal.dictionary + public static let dictionary: SourceLangSwiftLiteral = "source.lang.swift.literal.dictionary" + /// source.lang.swift.literal.image + public static let image: SourceLangSwiftLiteral = "source.lang.swift.literal.image" + /// source.lang.swift.literal.integer + public static let integer: SourceLangSwiftLiteral = "source.lang.swift.literal.integer" + /// source.lang.swift.literal.nil + public static let `nil`: SourceLangSwiftLiteral = "source.lang.swift.literal.nil" + /// source.lang.swift.literal.string + public static let string: SourceLangSwiftLiteral = "source.lang.swift.literal.string" + /// source.lang.swift.literal.tuple + public static let tuple: SourceLangSwiftLiteral = "source.lang.swift.literal.tuple" + } + public struct SourceLangSwiftRef { + public let uid: UID + /// source.lang.swift.ref.associatedtype + public static let `associatedtype`: SourceLangSwiftRef = "source.lang.swift.ref.associatedtype" + /// source.lang.swift.ref.class + public static let `class`: SourceLangSwiftRef = "source.lang.swift.ref.class" + /// source.lang.swift.ref.enum + public static let `enum`: SourceLangSwiftRef = "source.lang.swift.ref.enum" + /// source.lang.swift.ref.enumelement + public static let enumelement: SourceLangSwiftRef = "source.lang.swift.ref.enumelement" + /// source.lang.swift.ref.function.accessor.address + public static let functionAccessorAddress: SourceLangSwiftRef = "source.lang.swift.ref.function.accessor.address" + /// source.lang.swift.ref.function.accessor.didset + public static let functionAccessorDidset: SourceLangSwiftRef = "source.lang.swift.ref.function.accessor.didset" + /// source.lang.swift.ref.function.accessor.getter + public static let functionAccessorGetter: SourceLangSwiftRef = "source.lang.swift.ref.function.accessor.getter" + /// source.lang.swift.ref.function.accessor.mutableaddress + public static let functionAccessorMutableaddress: SourceLangSwiftRef = "source.lang.swift.ref.function.accessor.mutableaddress" + /// source.lang.swift.ref.function.accessor.setter + public static let functionAccessorSetter: SourceLangSwiftRef = "source.lang.swift.ref.function.accessor.setter" + /// source.lang.swift.ref.function.accessor.willset + public static let functionAccessorWillset: SourceLangSwiftRef = "source.lang.swift.ref.function.accessor.willset" + /// source.lang.swift.ref.function.constructor + public static let functionConstructor: SourceLangSwiftRef = "source.lang.swift.ref.function.constructor" + /// source.lang.swift.ref.function.destructor + public static let functionDestructor: SourceLangSwiftRef = "source.lang.swift.ref.function.destructor" + /// source.lang.swift.ref.function.free + public static let functionFree: SourceLangSwiftRef = "source.lang.swift.ref.function.free" + /// source.lang.swift.ref.function.method.class + public static let functionMethodClass: SourceLangSwiftRef = "source.lang.swift.ref.function.method.class" + /// source.lang.swift.ref.function.method.instance + public static let functionMethodInstance: SourceLangSwiftRef = "source.lang.swift.ref.function.method.instance" + /// source.lang.swift.ref.function.method.static + public static let functionMethodStatic: SourceLangSwiftRef = "source.lang.swift.ref.function.method.static" + /// source.lang.swift.ref.function.operator.infix + public static let functionOperatorInfix: SourceLangSwiftRef = "source.lang.swift.ref.function.operator.infix" + /// source.lang.swift.ref.function.operator.postfix + public static let functionOperatorPostfix: SourceLangSwiftRef = "source.lang.swift.ref.function.operator.postfix" + /// source.lang.swift.ref.function.operator.prefix + public static let functionOperatorPrefix: SourceLangSwiftRef = "source.lang.swift.ref.function.operator.prefix" + /// source.lang.swift.ref.function.subscript + public static let functionSubscript: SourceLangSwiftRef = "source.lang.swift.ref.function.subscript" + /// source.lang.swift.ref.generic_type_param + public static let generic_type_param: SourceLangSwiftRef = "source.lang.swift.ref.generic_type_param" + /// source.lang.swift.ref.module + public static let module: SourceLangSwiftRef = "source.lang.swift.ref.module" + /// source.lang.swift.ref.precedencegroup + public static let `precedencegroup`: SourceLangSwiftRef = "source.lang.swift.ref.precedencegroup" + /// source.lang.swift.ref.protocol + public static let `protocol`: SourceLangSwiftRef = "source.lang.swift.ref.protocol" + /// source.lang.swift.ref.struct + public static let `struct`: SourceLangSwiftRef = "source.lang.swift.ref.struct" + /// source.lang.swift.ref.typealias + public static let `typealias`: SourceLangSwiftRef = "source.lang.swift.ref.typealias" + /// source.lang.swift.ref.var.class + public static let varClass: SourceLangSwiftRef = "source.lang.swift.ref.var.class" + /// source.lang.swift.ref.var.global + public static let varGlobal: SourceLangSwiftRef = "source.lang.swift.ref.var.global" + /// source.lang.swift.ref.var.instance + public static let varInstance: SourceLangSwiftRef = "source.lang.swift.ref.var.instance" + /// source.lang.swift.ref.var.local + public static let varLocal: SourceLangSwiftRef = "source.lang.swift.ref.var.local" + /// source.lang.swift.ref.var.static + public static let varStatic: SourceLangSwiftRef = "source.lang.swift.ref.var.static" + } + public struct SourceLangSwiftStmt { + public let uid: UID + /// source.lang.swift.stmt.brace + public static let brace: SourceLangSwiftStmt = "source.lang.swift.stmt.brace" + /// source.lang.swift.stmt.case + public static let `case`: SourceLangSwiftStmt = "source.lang.swift.stmt.case" + /// source.lang.swift.stmt.for + public static let `for`: SourceLangSwiftStmt = "source.lang.swift.stmt.for" + /// source.lang.swift.stmt.foreach + public static let foreach: SourceLangSwiftStmt = "source.lang.swift.stmt.foreach" + /// source.lang.swift.stmt.guard + public static let `guard`: SourceLangSwiftStmt = "source.lang.swift.stmt.guard" + /// source.lang.swift.stmt.if + public static let `if`: SourceLangSwiftStmt = "source.lang.swift.stmt.if" + /// source.lang.swift.stmt.repeatwhile + public static let repeatwhile: SourceLangSwiftStmt = "source.lang.swift.stmt.repeatwhile" + /// source.lang.swift.stmt.switch + public static let `switch`: SourceLangSwiftStmt = "source.lang.swift.stmt.switch" + /// source.lang.swift.stmt.while + public static let `while`: SourceLangSwiftStmt = "source.lang.swift.stmt.while" + } + public struct SourceLangSwiftStructureElem { + public let uid: UID + /// source.lang.swift.structure.elem.condition_expr + public static let condition_expr: SourceLangSwiftStructureElem = "source.lang.swift.structure.elem.condition_expr" + /// source.lang.swift.structure.elem.expr + public static let expr: SourceLangSwiftStructureElem = "source.lang.swift.structure.elem.expr" + /// source.lang.swift.structure.elem.id + public static let id: SourceLangSwiftStructureElem = "source.lang.swift.structure.elem.id" + /// source.lang.swift.structure.elem.init_expr + public static let init_expr: SourceLangSwiftStructureElem = "source.lang.swift.structure.elem.init_expr" + /// source.lang.swift.structure.elem.pattern + public static let pattern: SourceLangSwiftStructureElem = "source.lang.swift.structure.elem.pattern" + /// source.lang.swift.structure.elem.typeref + public static let typeref: SourceLangSwiftStructureElem = "source.lang.swift.structure.elem.typeref" + } + public struct SourceLangSwiftSyntaxtype { + public let uid: UID + /// source.lang.swift.syntaxtype.argument + public static let argument: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.argument" + /// source.lang.swift.syntaxtype.attribute.builtin + public static let attributeBuiltin: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.attribute.builtin" + /// source.lang.swift.syntaxtype.attribute.id + public static let attributeId: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.attribute.id" + /// source.lang.swift.syntaxtype.buildconfig.id + public static let buildconfigId: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.buildconfig.id" + /// source.lang.swift.syntaxtype.buildconfig.keyword + public static let buildconfigKeyword: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.buildconfig.keyword" + /// source.lang.swift.syntaxtype.comment + public static let comment: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.comment" + /// source.lang.swift.syntaxtype.comment.mark + public static let commentMark: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.comment.mark" + /// source.lang.swift.syntaxtype.comment.url + public static let commentUrl: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.comment.url" + /// source.lang.swift.syntaxtype.doccomment + public static let doccomment: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.doccomment" + /// source.lang.swift.syntaxtype.doccomment.field + public static let doccommentField: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.doccomment.field" + /// source.lang.swift.syntaxtype.identifier + public static let identifier: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.identifier" + /// source.lang.swift.syntaxtype.keyword + public static let keyword: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.keyword" + /// source.lang.swift.syntaxtype.number + public static let number: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.number" + /// source.lang.swift.syntaxtype.objectliteral + public static let objectliteral: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.objectliteral" + /// source.lang.swift.syntaxtype.parameter + public static let parameter: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.parameter" + /// source.lang.swift.syntaxtype.placeholder + public static let placeholder: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.placeholder" + /// source.lang.swift.syntaxtype.string + public static let string: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.string" + /// source.lang.swift.syntaxtype.string_interpolation_anchor + public static let string_interpolation_anchor: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.string_interpolation_anchor" + /// source.lang.swift.syntaxtype.typeidentifier + public static let typeidentifier: SourceLangSwiftSyntaxtype = "source.lang.swift.syntaxtype.typeidentifier" + } + public struct SourceNotification { + public let uid: UID + /// source.notification.editor.documentupdate + public static let editorDocumentupdate: SourceNotification = "source.notification.editor.documentupdate" + /// source.notification.sema_disabled + public static let sema_disabled: SourceNotification = "source.notification.sema_disabled" + } + public struct SourceRequest { + public let uid: UID + /// source.request.buildsettings.register + public static let buildsettingsRegister: SourceRequest = "source.request.buildsettings.register" + /// source.request.codecomplete + public static let codecomplete: SourceRequest = "source.request.codecomplete" + /// source.request.codecomplete.cache.ondisk + public static let codecompleteCacheOndisk: SourceRequest = "source.request.codecomplete.cache.ondisk" + /// source.request.codecomplete.close + public static let codecompleteClose: SourceRequest = "source.request.codecomplete.close" + /// source.request.codecomplete.open + public static let codecompleteOpen: SourceRequest = "source.request.codecomplete.open" + /// source.request.codecomplete.setcustom + public static let codecompleteSetcustom: SourceRequest = "source.request.codecomplete.setcustom" + /// source.request.codecomplete.setpopularapi + public static let codecompleteSetpopularapi: SourceRequest = "source.request.codecomplete.setpopularapi" + /// source.request.codecomplete.update + public static let codecompleteUpdate: SourceRequest = "source.request.codecomplete.update" + /// source.request.crash_exit + public static let crash_exit: SourceRequest = "source.request.crash_exit" + /// source.request.cursorinfo + public static let cursorinfo: SourceRequest = "source.request.cursorinfo" + /// source.request.demangle + public static let demangle: SourceRequest = "source.request.demangle" + /// source.request.docinfo + public static let docinfo: SourceRequest = "source.request.docinfo" + /// source.request.editor.close + public static let editorClose: SourceRequest = "source.request.editor.close" + /// source.request.editor.expand_placeholder + public static let editorExpand_Placeholder: SourceRequest = "source.request.editor.expand_placeholder" + /// source.request.editor.extract.comment + public static let editorExtractComment: SourceRequest = "source.request.editor.extract.comment" + /// source.request.editor.find_interface_doc + public static let editorFind_Interface_Doc: SourceRequest = "source.request.editor.find_interface_doc" + /// source.request.editor.find_usr + public static let editorFind_Usr: SourceRequest = "source.request.editor.find_usr" + /// source.request.editor.formattext + public static let editorFormattext: SourceRequest = "source.request.editor.formattext" + /// source.request.editor.open + public static let editorOpen: SourceRequest = "source.request.editor.open" + /// source.request.editor.open.interface + public static let editorOpenInterface: SourceRequest = "source.request.editor.open.interface" + /// source.request.editor.open.interface.header + public static let editorOpenInterfaceHeader: SourceRequest = "source.request.editor.open.interface.header" + /// source.request.editor.open.interface.swiftsource + public static let editorOpenInterfaceSwiftsource: SourceRequest = "source.request.editor.open.interface.swiftsource" + /// source.request.editor.open.interface.swifttype + public static let editorOpenInterfaceSwifttype: SourceRequest = "source.request.editor.open.interface.swifttype" + /// source.request.editor.replacetext + public static let editorReplacetext: SourceRequest = "source.request.editor.replacetext" + /// source.request.indexsource + public static let indexsource: SourceRequest = "source.request.indexsource" + /// source.request.mangle_simple_class + public static let mangle_simple_class: SourceRequest = "source.request.mangle_simple_class" + /// source.request.module.groups + public static let moduleGroups: SourceRequest = "source.request.module.groups" + /// source.request.protocol_version + public static let protocol_version: SourceRequest = "source.request.protocol_version" + /// source.request.rangeinfo + public static let rangeinfo: SourceRequest = "source.request.rangeinfo" + /// source.request.relatedidents + public static let relatedidents: SourceRequest = "source.request.relatedidents" + } +} + +extension UID.Key: UIDNamespace { + public static let __uid_prefix = "key" + public static func == (lhs: UID.Key, rhs: UID.Key) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.Key, rhs: UID.Key) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.Key) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.Key) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.Key, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.Key, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.Key) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.Key) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.Key, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.Key, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceAvailabilityPlatform: UIDNamespace { + public static let __uid_prefix = "source.availability.platform" + public static func == (lhs: UID.SourceAvailabilityPlatform, rhs: UID.SourceAvailabilityPlatform) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceAvailabilityPlatform, rhs: UID.SourceAvailabilityPlatform) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceAvailabilityPlatform) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceAvailabilityPlatform) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceAvailabilityPlatform, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceAvailabilityPlatform, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceAvailabilityPlatform) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceAvailabilityPlatform) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceAvailabilityPlatform, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceAvailabilityPlatform, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceCodecompletion: UIDNamespace { + public static let __uid_prefix = "source.codecompletion" + public static func == (lhs: UID.SourceCodecompletion, rhs: UID.SourceCodecompletion) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceCodecompletion, rhs: UID.SourceCodecompletion) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceCodecompletion) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceCodecompletion) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceCodecompletion, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceCodecompletion, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceCodecompletion) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceCodecompletion) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceCodecompletion, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceCodecompletion, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceDeclAttribute: UIDNamespace { + public static let __uid_prefix = "source.decl.attribute" + public static func == (lhs: UID.SourceDeclAttribute, rhs: UID.SourceDeclAttribute) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceDeclAttribute, rhs: UID.SourceDeclAttribute) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceDeclAttribute) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceDeclAttribute) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceDeclAttribute, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceDeclAttribute, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceDeclAttribute) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceDeclAttribute) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceDeclAttribute, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceDeclAttribute, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceDiagnosticSeverity: UIDNamespace { + public static let __uid_prefix = "source.diagnostic.severity" + public static func == (lhs: UID.SourceDiagnosticSeverity, rhs: UID.SourceDiagnosticSeverity) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceDiagnosticSeverity, rhs: UID.SourceDiagnosticSeverity) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceDiagnosticSeverity) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceDiagnosticSeverity) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceDiagnosticSeverity, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceDiagnosticSeverity, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceDiagnosticSeverity) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceDiagnosticSeverity) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceDiagnosticSeverity, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceDiagnosticSeverity, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceDiagnosticStageSwift: UIDNamespace { + public static let __uid_prefix = "source.diagnostic.stage.swift" + public static func == (lhs: UID.SourceDiagnosticStageSwift, rhs: UID.SourceDiagnosticStageSwift) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceDiagnosticStageSwift, rhs: UID.SourceDiagnosticStageSwift) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceDiagnosticStageSwift) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceDiagnosticStageSwift) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceDiagnosticStageSwift, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceDiagnosticStageSwift, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceDiagnosticStageSwift) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceDiagnosticStageSwift) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceDiagnosticStageSwift, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceDiagnosticStageSwift, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceLangSwift: UIDNamespace { + public static let __uid_prefix = "source.lang.swift" + public static func == (lhs: UID.SourceLangSwift, rhs: UID.SourceLangSwift) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceLangSwift, rhs: UID.SourceLangSwift) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceLangSwift) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceLangSwift) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceLangSwift, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceLangSwift, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceLangSwift) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceLangSwift) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceLangSwift, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceLangSwift, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceLangSwiftAccessibility: UIDNamespace { + public static let __uid_prefix = "source.lang.swift.accessibility" + public static func == (lhs: UID.SourceLangSwiftAccessibility, rhs: UID.SourceLangSwiftAccessibility) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceLangSwiftAccessibility, rhs: UID.SourceLangSwiftAccessibility) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceLangSwiftAccessibility) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceLangSwiftAccessibility) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceLangSwiftAccessibility, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceLangSwiftAccessibility, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceLangSwiftAccessibility) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceLangSwiftAccessibility) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceLangSwiftAccessibility, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceLangSwiftAccessibility, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceLangSwiftAttribute: UIDNamespace { + public static let __uid_prefix = "source.lang.swift.attribute" + public static func == (lhs: UID.SourceLangSwiftAttribute, rhs: UID.SourceLangSwiftAttribute) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceLangSwiftAttribute, rhs: UID.SourceLangSwiftAttribute) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceLangSwiftAttribute) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceLangSwiftAttribute) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceLangSwiftAttribute, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceLangSwiftAttribute, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceLangSwiftAttribute) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceLangSwiftAttribute) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceLangSwiftAttribute, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceLangSwiftAttribute, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceLangSwiftCodecomplete: UIDNamespace { + public static let __uid_prefix = "source.lang.swift.codecomplete" + public static func == (lhs: UID.SourceLangSwiftCodecomplete, rhs: UID.SourceLangSwiftCodecomplete) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceLangSwiftCodecomplete, rhs: UID.SourceLangSwiftCodecomplete) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceLangSwiftCodecomplete) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceLangSwiftCodecomplete) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceLangSwiftCodecomplete, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceLangSwiftCodecomplete, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceLangSwiftCodecomplete) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceLangSwiftCodecomplete) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceLangSwiftCodecomplete, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceLangSwiftCodecomplete, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceLangSwiftDecl: UIDNamespace { + public static let __uid_prefix = "source.lang.swift.decl" + public static func == (lhs: UID.SourceLangSwiftDecl, rhs: UID.SourceLangSwiftDecl) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceLangSwiftDecl, rhs: UID.SourceLangSwiftDecl) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceLangSwiftDecl) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceLangSwiftDecl) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceLangSwiftDecl, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceLangSwiftDecl, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceLangSwiftDecl) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceLangSwiftDecl) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceLangSwiftDecl, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceLangSwiftDecl, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceLangSwiftExpr: UIDNamespace { + public static let __uid_prefix = "source.lang.swift.expr" + public static func == (lhs: UID.SourceLangSwiftExpr, rhs: UID.SourceLangSwiftExpr) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceLangSwiftExpr, rhs: UID.SourceLangSwiftExpr) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceLangSwiftExpr) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceLangSwiftExpr) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceLangSwiftExpr, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceLangSwiftExpr, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceLangSwiftExpr) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceLangSwiftExpr) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceLangSwiftExpr, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceLangSwiftExpr, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceLangSwiftImportModule: UIDNamespace { + public static let __uid_prefix = "source.lang.swift.import.module" + public static func == (lhs: UID.SourceLangSwiftImportModule, rhs: UID.SourceLangSwiftImportModule) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceLangSwiftImportModule, rhs: UID.SourceLangSwiftImportModule) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceLangSwiftImportModule) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceLangSwiftImportModule) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceLangSwiftImportModule, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceLangSwiftImportModule, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceLangSwiftImportModule) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceLangSwiftImportModule) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceLangSwiftImportModule, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceLangSwiftImportModule, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceLangSwiftKeyword: UIDNamespace { + public static let __uid_prefix = "source.lang.swift.keyword" + public static func == (lhs: UID.SourceLangSwiftKeyword, rhs: UID.SourceLangSwiftKeyword) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceLangSwiftKeyword, rhs: UID.SourceLangSwiftKeyword) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceLangSwiftKeyword) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceLangSwiftKeyword) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceLangSwiftKeyword, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceLangSwiftKeyword, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceLangSwiftKeyword) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceLangSwiftKeyword) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceLangSwiftKeyword, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceLangSwiftKeyword, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceLangSwiftLiteral: UIDNamespace { + public static let __uid_prefix = "source.lang.swift.literal" + public static func == (lhs: UID.SourceLangSwiftLiteral, rhs: UID.SourceLangSwiftLiteral) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceLangSwiftLiteral, rhs: UID.SourceLangSwiftLiteral) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceLangSwiftLiteral) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceLangSwiftLiteral) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceLangSwiftLiteral, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceLangSwiftLiteral, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceLangSwiftLiteral) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceLangSwiftLiteral) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceLangSwiftLiteral, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceLangSwiftLiteral, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceLangSwiftRef: UIDNamespace { + public static let __uid_prefix = "source.lang.swift.ref" + public static func == (lhs: UID.SourceLangSwiftRef, rhs: UID.SourceLangSwiftRef) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceLangSwiftRef, rhs: UID.SourceLangSwiftRef) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceLangSwiftRef) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceLangSwiftRef) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceLangSwiftRef, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceLangSwiftRef, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceLangSwiftRef) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceLangSwiftRef) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceLangSwiftRef, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceLangSwiftRef, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceLangSwiftStmt: UIDNamespace { + public static let __uid_prefix = "source.lang.swift.stmt" + public static func == (lhs: UID.SourceLangSwiftStmt, rhs: UID.SourceLangSwiftStmt) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceLangSwiftStmt, rhs: UID.SourceLangSwiftStmt) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceLangSwiftStmt) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceLangSwiftStmt) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceLangSwiftStmt, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceLangSwiftStmt, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceLangSwiftStmt) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceLangSwiftStmt) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceLangSwiftStmt, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceLangSwiftStmt, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceLangSwiftStructureElem: UIDNamespace { + public static let __uid_prefix = "source.lang.swift.structure.elem" + public static func == (lhs: UID.SourceLangSwiftStructureElem, rhs: UID.SourceLangSwiftStructureElem) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceLangSwiftStructureElem, rhs: UID.SourceLangSwiftStructureElem) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceLangSwiftStructureElem) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceLangSwiftStructureElem) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceLangSwiftStructureElem, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceLangSwiftStructureElem, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceLangSwiftStructureElem) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceLangSwiftStructureElem) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceLangSwiftStructureElem, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceLangSwiftStructureElem, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceLangSwiftSyntaxtype: UIDNamespace { + public static let __uid_prefix = "source.lang.swift.syntaxtype" + public static func == (lhs: UID.SourceLangSwiftSyntaxtype, rhs: UID.SourceLangSwiftSyntaxtype) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceLangSwiftSyntaxtype, rhs: UID.SourceLangSwiftSyntaxtype) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceLangSwiftSyntaxtype) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceLangSwiftSyntaxtype) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceLangSwiftSyntaxtype, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceLangSwiftSyntaxtype, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceLangSwiftSyntaxtype) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceLangSwiftSyntaxtype) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceLangSwiftSyntaxtype, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceLangSwiftSyntaxtype, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceNotification: UIDNamespace { + public static let __uid_prefix = "source.notification" + public static func == (lhs: UID.SourceNotification, rhs: UID.SourceNotification) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceNotification, rhs: UID.SourceNotification) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceNotification) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceNotification) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceNotification, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceNotification, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceNotification) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceNotification) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceNotification, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceNotification, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID.SourceRequest: UIDNamespace { + public static let __uid_prefix = "source.request" + public static func == (lhs: UID.SourceRequest, rhs: UID.SourceRequest) -> Bool { return lhs.uid == rhs.uid } + public static func != (lhs: UID.SourceRequest, rhs: UID.SourceRequest) -> Bool { return lhs.uid != rhs.uid } + public static func == (lhs: UID, rhs: UID.SourceRequest) -> Bool { return lhs == rhs.uid } + public static func != (lhs: UID, rhs: UID.SourceRequest) -> Bool { return lhs != rhs.uid } + public static func == (lhs: UID.SourceRequest, rhs: UID) -> Bool { return lhs.uid == rhs } + public static func != (lhs: UID.SourceRequest, rhs: UID) -> Bool { return lhs.uid != rhs } + public static func == (lhs: UID?, rhs: UID.SourceRequest) -> Bool { return lhs.map { $0 == rhs.uid } ?? false } + public static func != (lhs: UID?, rhs: UID.SourceRequest) -> Bool { return lhs.map { $0 != rhs.uid } ?? true } + public static func == (lhs: UID.SourceRequest, rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false } + public static func != (lhs: UID.SourceRequest, rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true } + public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } + public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) } +} +extension UID { + public var isMemberOfKey: Bool { return knownUIDsOfKey.contains(self) } + public var isMemberOfSourceAvailabilityPlatform: Bool { return knownUIDsOfSourceAvailabilityPlatform.contains(self) } + public var isMemberOfSourceCodecompletion: Bool { return knownUIDsOfSourceCodecompletion.contains(self) } + public var isMemberOfSourceDeclAttribute: Bool { return knownUIDsOfSourceDeclAttribute.contains(self) } + public var isMemberOfSourceDiagnosticSeverity: Bool { return knownUIDsOfSourceDiagnosticSeverity.contains(self) } + public var isMemberOfSourceDiagnosticStageSwift: Bool { return knownUIDsOfSourceDiagnosticStageSwift.contains(self) } + public var isMemberOfSourceLangSwift: Bool { return knownUIDsOfSourceLangSwift.contains(self) } + public var isMemberOfSourceLangSwiftAccessibility: Bool { return knownUIDsOfSourceLangSwiftAccessibility.contains(self) } + public var isMemberOfSourceLangSwiftAttribute: Bool { return knownUIDsOfSourceLangSwiftAttribute.contains(self) } + public var isMemberOfSourceLangSwiftCodecomplete: Bool { return knownUIDsOfSourceLangSwiftCodecomplete.contains(self) } + public var isMemberOfSourceLangSwiftDecl: Bool { return knownUIDsOfSourceLangSwiftDecl.contains(self) } + public var isMemberOfSourceLangSwiftExpr: Bool { return knownUIDsOfSourceLangSwiftExpr.contains(self) } + public var isMemberOfSourceLangSwiftImportModule: Bool { return knownUIDsOfSourceLangSwiftImportModule.contains(self) } + public var isMemberOfSourceLangSwiftKeyword: Bool { return knownUIDsOfSourceLangSwiftKeyword.contains(self) } + public var isMemberOfSourceLangSwiftLiteral: Bool { return knownUIDsOfSourceLangSwiftLiteral.contains(self) } + public var isMemberOfSourceLangSwiftRef: Bool { return knownUIDsOfSourceLangSwiftRef.contains(self) } + public var isMemberOfSourceLangSwiftStmt: Bool { return knownUIDsOfSourceLangSwiftStmt.contains(self) } + public var isMemberOfSourceLangSwiftStructureElem: Bool { return knownUIDsOfSourceLangSwiftStructureElem.contains(self) } + public var isMemberOfSourceLangSwiftSyntaxtype: Bool { return knownUIDsOfSourceLangSwiftSyntaxtype.contains(self) } + public var isMemberOfSourceNotification: Bool { return knownUIDsOfSourceNotification.contains(self) } + public var isMemberOfSourceRequest: Bool { return knownUIDsOfSourceRequest.contains(self) } +} +fileprivate let knownUIDsOfKey: Set = [ + UID.Key.accessibility.uid, + UID.Key.actionable.uid, + UID.Key.actionname.uid, + UID.Key.annotated_decl.uid, + UID.Key.annotations.uid, + UID.Key.associated_usrs.uid, + UID.Key.attribute.uid, + UID.Key.attributes.uid, + UID.Key.bodylength.uid, + UID.Key.bodyoffset.uid, + UID.Key.codecompleteAddinitstotoplevel.uid, + UID.Key.codecompleteAddinneroperators.uid, + UID.Key.codecompleteAddinnerresults.uid, + UID.Key.codecompleteFilterrules.uid, + UID.Key.codecompleteFiltertext.uid, + UID.Key.codecompleteFuzzymatching.uid, + UID.Key.codecompleteGroupOverloads.uid, + UID.Key.codecompleteGroupStems.uid, + UID.Key.codecompleteHidebyname.uid, + UID.Key.codecompleteHidelowpriority.uid, + UID.Key.codecompleteHideunderscores.uid, + UID.Key.codecompleteIncludeexactmatch.uid, + UID.Key.codecompleteOptions.uid, + UID.Key.codecompleteRequestlimit.uid, + UID.Key.codecompleteRequeststart.uid, + UID.Key.codecompleteShowtopnonliteralresults.uid, + UID.Key.codecompleteSortByname.uid, + UID.Key.codecompleteSortContextweight.uid, + UID.Key.codecompleteSortFuzzyweight.uid, + UID.Key.codecompleteSortPopularitybonus.uid, + UID.Key.codecompleteSortUseimportdepth.uid, + UID.Key.column.uid, + UID.Key.compilerargs.uid, + UID.Key.conforms.uid, + UID.Key.containertypeusr.uid, + UID.Key.context.uid, + UID.Key.default_implementation_of.uid, + UID.Key.dependencies.uid, + UID.Key.deprecated.uid, + UID.Key.description.uid, + UID.Key.diagnostic_stage.uid, + UID.Key.diagnostics.uid, + UID.Key.docBrief.uid, + UID.Key.docFull_As_Xml.uid, + UID.Key.duration.uid, + UID.Key.editorFormatIndentwidth.uid, + UID.Key.editorFormatOptions.uid, + UID.Key.editorFormatTabwidth.uid, + UID.Key.editorFormatUsetabs.uid, + UID.Key.elements.uid, + UID.Key.enablediagnostics.uid, + UID.Key.enablesubstructure.uid, + UID.Key.enablesyntaxmap.uid, + UID.Key.entities.uid, + UID.Key.extends.uid, + UID.Key.filepath.uid, + UID.Key.fixits.uid, + UID.Key.fully_annotated_decl.uid, + UID.Key.generic_params.uid, + UID.Key.generic_requirements.uid, + UID.Key.groupname.uid, + UID.Key.hash.uid, + UID.Key.hide.uid, + UID.Key.inheritedtypes.uid, + UID.Key.inherits.uid, + UID.Key.interested_usr.uid, + UID.Key.introduced.uid, + UID.Key.is_deprecated.uid, + UID.Key.is_dynamic.uid, + UID.Key.is_local.uid, + UID.Key.is_optional.uid, + UID.Key.is_system.uid, + UID.Key.is_test_candidate.uid, + UID.Key.is_unavailable.uid, + UID.Key.keyword.uid, + UID.Key.kind.uid, + UID.Key.length.uid, + UID.Key.line.uid, + UID.Key.message.uid, + UID.Key.module_interface_name.uid, + UID.Key.modulegroups.uid, + UID.Key.moduleimportdepth.uid, + UID.Key.modulename.uid, + UID.Key.name.uid, + UID.Key.namelength.uid, + UID.Key.nameoffset.uid, + UID.Key.names.uid, + UID.Key.nextrequeststart.uid, + UID.Key.not_recommended.uid, + UID.Key.notification.uid, + UID.Key.num_bytes_to_erase.uid, + UID.Key.obsoleted.uid, + UID.Key.offset.uid, + UID.Key.original_usr.uid, + UID.Key.overrides.uid, + UID.Key.platform.uid, + UID.Key.popular.uid, + UID.Key.rangecontent.uid, + UID.Key.ranges.uid, + UID.Key.receiver_usr.uid, + UID.Key.related.uid, + UID.Key.related_decls.uid, + UID.Key.removecache.uid, + UID.Key.request.uid, + UID.Key.results.uid, + UID.Key.runtime_name.uid, + UID.Key.selector_name.uid, + UID.Key.setter_accessibility.uid, + UID.Key.severity.uid, + UID.Key.simplified.uid, + UID.Key.sourcefile.uid, + UID.Key.sourcetext.uid, + UID.Key.substructure.uid, + UID.Key.syntactic_only.uid, + UID.Key.syntaxmap.uid, + UID.Key.synthesizedextensions.uid, + UID.Key.throwlength.uid, + UID.Key.throwoffset.uid, + UID.Key.typeinterface.uid, + UID.Key.typename.uid, + UID.Key.typeusr.uid, + UID.Key.uids.uid, + UID.Key.unpopular.uid, + UID.Key.usr.uid, + UID.Key.version_major.uid, + UID.Key.version_minor.uid, +] +fileprivate let knownUIDsOfSourceAvailabilityPlatform: Set = [ + UID.SourceAvailabilityPlatform.ios.uid, + UID.SourceAvailabilityPlatform.ios_app_extension.uid, + UID.SourceAvailabilityPlatform.osx.uid, + UID.SourceAvailabilityPlatform.osx_app_extension.uid, + UID.SourceAvailabilityPlatform.tvos.uid, + UID.SourceAvailabilityPlatform.tvos_app_extension.uid, + UID.SourceAvailabilityPlatform.watchos.uid, + UID.SourceAvailabilityPlatform.watchos_app_extension.uid, +] +fileprivate let knownUIDsOfSourceCodecompletion: Set = [ + UID.SourceCodecompletion.contextExprspecific.uid, + UID.SourceCodecompletion.contextLocal.uid, + UID.SourceCodecompletion.contextNone.uid, + UID.SourceCodecompletion.contextOtherclass.uid, + UID.SourceCodecompletion.contextOthermodule.uid, + UID.SourceCodecompletion.contextSuperclass.uid, + UID.SourceCodecompletion.contextThisclass.uid, + UID.SourceCodecompletion.contextThismodule.uid, + UID.SourceCodecompletion.custom.uid, + UID.SourceCodecompletion.everything.uid, + UID.SourceCodecompletion.identifier.uid, + UID.SourceCodecompletion.keyword.uid, + UID.SourceCodecompletion.literal.uid, + UID.SourceCodecompletion.module.uid, +] +fileprivate let knownUIDsOfSourceDeclAttribute: Set = [ + UID.SourceDeclAttribute.LLDBDebuggerFunction.uid, + UID.SourceDeclAttribute.NSApplicationMain.uid, + UID.SourceDeclAttribute.NSCopying.uid, + UID.SourceDeclAttribute.NSManaged.uid, + UID.SourceDeclAttribute.UIApplicationMain.uid, + UID.SourceDeclAttribute.__objc_bridged.uid, + UID.SourceDeclAttribute.__synthesized_protocol.uid, + UID.SourceDeclAttribute._alignment.uid, + UID.SourceDeclAttribute._cdecl.uid, + UID.SourceDeclAttribute._exported.uid, + UID.SourceDeclAttribute._fixed_layout.uid, + UID.SourceDeclAttribute._inlineable.uid, + UID.SourceDeclAttribute._semantics.uid, + UID.SourceDeclAttribute._silgen_name.uid, + UID.SourceDeclAttribute._specialize.uid, + UID.SourceDeclAttribute._swift_native_objc_runtime_base.uid, + UID.SourceDeclAttribute._transparent.uid, + UID.SourceDeclAttribute._versioned.uid, + UID.SourceDeclAttribute.autoclosure.uid, + UID.SourceDeclAttribute.available.uid, + UID.SourceDeclAttribute.convenience.uid, + UID.SourceDeclAttribute.discardableResult.uid, + UID.SourceDeclAttribute.dynamic.uid, + UID.SourceDeclAttribute.effects.uid, + UID.SourceDeclAttribute.final.uid, + UID.SourceDeclAttribute.gkinspectable.uid, + UID.SourceDeclAttribute.ibaction.uid, + UID.SourceDeclAttribute.ibdesignable.uid, + UID.SourceDeclAttribute.ibinspectable.uid, + UID.SourceDeclAttribute.iboutlet.uid, + UID.SourceDeclAttribute.indirect.uid, + UID.SourceDeclAttribute.infix.uid, + UID.SourceDeclAttribute.inline.uid, + UID.SourceDeclAttribute.lazy.uid, + UID.SourceDeclAttribute.mutating.uid, + UID.SourceDeclAttribute.noescape.uid, + UID.SourceDeclAttribute.nonmutating.uid, + UID.SourceDeclAttribute.nonobjc.uid, + UID.SourceDeclAttribute.noreturn.uid, + UID.SourceDeclAttribute.objc.uid, + UID.SourceDeclAttribute.objcName.uid, + UID.SourceDeclAttribute.objc_non_lazy_realization.uid, + UID.SourceDeclAttribute.optional.uid, + UID.SourceDeclAttribute.override.uid, + UID.SourceDeclAttribute.postfix.uid, + UID.SourceDeclAttribute.prefix.uid, + UID.SourceDeclAttribute.required.uid, + UID.SourceDeclAttribute.requires_stored_property_inits.uid, + UID.SourceDeclAttribute.`rethrows`.uid, + UID.SourceDeclAttribute.sil_stored.uid, + UID.SourceDeclAttribute.testable.uid, + UID.SourceDeclAttribute.unsafe_no_objc_tagged_pointer.uid, + UID.SourceDeclAttribute.warn_unqualified_access.uid, + UID.SourceDeclAttribute.weak.uid, +] +fileprivate let knownUIDsOfSourceDiagnosticSeverity: Set = [ + UID.SourceDiagnosticSeverity.error.uid, + UID.SourceDiagnosticSeverity.note.uid, + UID.SourceDiagnosticSeverity.warning.uid, +] +fileprivate let knownUIDsOfSourceDiagnosticStageSwift: Set = [ + UID.SourceDiagnosticStageSwift.parse.uid, + UID.SourceDiagnosticStageSwift.sema.uid, +] +fileprivate let knownUIDsOfSourceLangSwift: Set = [ + UID.SourceLangSwift.expr.uid, + UID.SourceLangSwift.keyword.uid, + UID.SourceLangSwift.pattern.uid, + UID.SourceLangSwift.rangeInvalid.uid, + UID.SourceLangSwift.rangeMultistatement.uid, + UID.SourceLangSwift.rangeSingledeclaration.uid, + UID.SourceLangSwift.rangeSingleexpression.uid, + UID.SourceLangSwift.rangeSinglestatement.uid, + UID.SourceLangSwift.stmt.uid, + UID.SourceLangSwift.type.uid, +] +fileprivate let knownUIDsOfSourceLangSwiftAccessibility: Set = [ + UID.SourceLangSwiftAccessibility.`fileprivate`.uid, + UID.SourceLangSwiftAccessibility.`internal`.uid, + UID.SourceLangSwiftAccessibility.open.uid, + UID.SourceLangSwiftAccessibility.`private`.uid, + UID.SourceLangSwiftAccessibility.`public`.uid, +] +fileprivate let knownUIDsOfSourceLangSwiftAttribute: Set = [ + UID.SourceLangSwiftAttribute.availability.uid, +] +fileprivate let knownUIDsOfSourceLangSwiftCodecomplete: Set = [ + UID.SourceLangSwiftCodecomplete.group.uid, +] +fileprivate let knownUIDsOfSourceLangSwiftDecl: Set = [ + UID.SourceLangSwiftDecl.`associatedtype`.uid, + UID.SourceLangSwiftDecl.`class`.uid, + UID.SourceLangSwiftDecl.`enum`.uid, + UID.SourceLangSwiftDecl.enumcase.uid, + UID.SourceLangSwiftDecl.enumelement.uid, + UID.SourceLangSwiftDecl.`extension`.uid, + UID.SourceLangSwiftDecl.extensionClass.uid, + UID.SourceLangSwiftDecl.extensionEnum.uid, + UID.SourceLangSwiftDecl.extensionProtocol.uid, + UID.SourceLangSwiftDecl.extensionStruct.uid, + UID.SourceLangSwiftDecl.functionAccessorAddress.uid, + UID.SourceLangSwiftDecl.functionAccessorDidset.uid, + UID.SourceLangSwiftDecl.functionAccessorGetter.uid, + UID.SourceLangSwiftDecl.functionAccessorMutableaddress.uid, + UID.SourceLangSwiftDecl.functionAccessorSetter.uid, + UID.SourceLangSwiftDecl.functionAccessorWillset.uid, + UID.SourceLangSwiftDecl.functionConstructor.uid, + UID.SourceLangSwiftDecl.functionDestructor.uid, + UID.SourceLangSwiftDecl.functionFree.uid, + UID.SourceLangSwiftDecl.functionMethodClass.uid, + UID.SourceLangSwiftDecl.functionMethodInstance.uid, + UID.SourceLangSwiftDecl.functionMethodStatic.uid, + UID.SourceLangSwiftDecl.functionOperatorInfix.uid, + UID.SourceLangSwiftDecl.functionOperatorPostfix.uid, + UID.SourceLangSwiftDecl.functionOperatorPrefix.uid, + UID.SourceLangSwiftDecl.functionSubscript.uid, + UID.SourceLangSwiftDecl.generic_type_param.uid, + UID.SourceLangSwiftDecl.module.uid, + UID.SourceLangSwiftDecl.`precedencegroup`.uid, + UID.SourceLangSwiftDecl.`protocol`.uid, + UID.SourceLangSwiftDecl.`struct`.uid, + UID.SourceLangSwiftDecl.`typealias`.uid, + UID.SourceLangSwiftDecl.varClass.uid, + UID.SourceLangSwiftDecl.varGlobal.uid, + UID.SourceLangSwiftDecl.varInstance.uid, + UID.SourceLangSwiftDecl.varLocal.uid, + UID.SourceLangSwiftDecl.varParameter.uid, + UID.SourceLangSwiftDecl.varStatic.uid, +] +fileprivate let knownUIDsOfSourceLangSwiftExpr: Set = [ + UID.SourceLangSwiftExpr.argument.uid, + UID.SourceLangSwiftExpr.array.uid, + UID.SourceLangSwiftExpr.call.uid, + UID.SourceLangSwiftExpr.dictionary.uid, + UID.SourceLangSwiftExpr.object_literal.uid, +] +fileprivate let knownUIDsOfSourceLangSwiftImportModule: Set = [ + UID.SourceLangSwiftImportModule.clang.uid, + UID.SourceLangSwiftImportModule.swift.uid, +] +fileprivate let knownUIDsOfSourceLangSwiftKeyword: Set = [ + UID.SourceLangSwiftKeyword.`Any`.uid, + UID.SourceLangSwiftKeyword.`Self`.uid, + UID.SourceLangSwiftKeyword.`_`.uid, + UID.SourceLangSwiftKeyword.`__COLUMN__`.uid, + UID.SourceLangSwiftKeyword.`__DSO_HANDLE__`.uid, + UID.SourceLangSwiftKeyword.`__FILE__`.uid, + UID.SourceLangSwiftKeyword.`__FUNCTION__`.uid, + UID.SourceLangSwiftKeyword.`__LINE__`.uid, + UID.SourceLangSwiftKeyword.`as`.uid, + UID.SourceLangSwiftKeyword.`associatedtype`.uid, + UID.SourceLangSwiftKeyword.`break`.uid, + UID.SourceLangSwiftKeyword.`case`.uid, + UID.SourceLangSwiftKeyword.`catch`.uid, + UID.SourceLangSwiftKeyword.`class`.uid, + UID.SourceLangSwiftKeyword.`continue`.uid, + UID.SourceLangSwiftKeyword.`default`.uid, + UID.SourceLangSwiftKeyword.`defer`.uid, + UID.SourceLangSwiftKeyword.`deinit`.uid, + UID.SourceLangSwiftKeyword.`do`.uid, + UID.SourceLangSwiftKeyword.`else`.uid, + UID.SourceLangSwiftKeyword.`enum`.uid, + UID.SourceLangSwiftKeyword.`extension`.uid, + UID.SourceLangSwiftKeyword.`fallthrough`.uid, + UID.SourceLangSwiftKeyword.`false`.uid, + UID.SourceLangSwiftKeyword.`fileprivate`.uid, + UID.SourceLangSwiftKeyword.`for`.uid, + UID.SourceLangSwiftKeyword.`func`.uid, + UID.SourceLangSwiftKeyword.`guard`.uid, + UID.SourceLangSwiftKeyword.`if`.uid, + UID.SourceLangSwiftKeyword.`import`.uid, + UID.SourceLangSwiftKeyword.`in`.uid, + UID.SourceLangSwiftKeyword.`init`.uid, + UID.SourceLangSwiftKeyword.`inout`.uid, + UID.SourceLangSwiftKeyword.`internal`.uid, + UID.SourceLangSwiftKeyword.`is`.uid, + UID.SourceLangSwiftKeyword.`let`.uid, + UID.SourceLangSwiftKeyword.`nil`.uid, + UID.SourceLangSwiftKeyword.`operator`.uid, + UID.SourceLangSwiftKeyword.`precedencegroup`.uid, + UID.SourceLangSwiftKeyword.`private`.uid, + UID.SourceLangSwiftKeyword.`protocol`.uid, + UID.SourceLangSwiftKeyword.`public`.uid, + UID.SourceLangSwiftKeyword.`repeat`.uid, + UID.SourceLangSwiftKeyword.`rethrows`.uid, + UID.SourceLangSwiftKeyword.`return`.uid, + UID.SourceLangSwiftKeyword.`self`.uid, + UID.SourceLangSwiftKeyword.`static`.uid, + UID.SourceLangSwiftKeyword.`struct`.uid, + UID.SourceLangSwiftKeyword.`subscript`.uid, + UID.SourceLangSwiftKeyword.`super`.uid, + UID.SourceLangSwiftKeyword.`switch`.uid, + UID.SourceLangSwiftKeyword.`throw`.uid, + UID.SourceLangSwiftKeyword.`throws`.uid, + UID.SourceLangSwiftKeyword.`true`.uid, + UID.SourceLangSwiftKeyword.`try`.uid, + UID.SourceLangSwiftKeyword.`typealias`.uid, + UID.SourceLangSwiftKeyword.`var`.uid, + UID.SourceLangSwiftKeyword.`where`.uid, + UID.SourceLangSwiftKeyword.`while`.uid, +] +fileprivate let knownUIDsOfSourceLangSwiftLiteral: Set = [ + UID.SourceLangSwiftLiteral.array.uid, + UID.SourceLangSwiftLiteral.boolean.uid, + UID.SourceLangSwiftLiteral.color.uid, + UID.SourceLangSwiftLiteral.dictionary.uid, + UID.SourceLangSwiftLiteral.image.uid, + UID.SourceLangSwiftLiteral.integer.uid, + UID.SourceLangSwiftLiteral.`nil`.uid, + UID.SourceLangSwiftLiteral.string.uid, + UID.SourceLangSwiftLiteral.tuple.uid, +] +fileprivate let knownUIDsOfSourceLangSwiftRef: Set = [ + UID.SourceLangSwiftRef.`associatedtype`.uid, + UID.SourceLangSwiftRef.`class`.uid, + UID.SourceLangSwiftRef.`enum`.uid, + UID.SourceLangSwiftRef.enumelement.uid, + UID.SourceLangSwiftRef.functionAccessorAddress.uid, + UID.SourceLangSwiftRef.functionAccessorDidset.uid, + UID.SourceLangSwiftRef.functionAccessorGetter.uid, + UID.SourceLangSwiftRef.functionAccessorMutableaddress.uid, + UID.SourceLangSwiftRef.functionAccessorSetter.uid, + UID.SourceLangSwiftRef.functionAccessorWillset.uid, + UID.SourceLangSwiftRef.functionConstructor.uid, + UID.SourceLangSwiftRef.functionDestructor.uid, + UID.SourceLangSwiftRef.functionFree.uid, + UID.SourceLangSwiftRef.functionMethodClass.uid, + UID.SourceLangSwiftRef.functionMethodInstance.uid, + UID.SourceLangSwiftRef.functionMethodStatic.uid, + UID.SourceLangSwiftRef.functionOperatorInfix.uid, + UID.SourceLangSwiftRef.functionOperatorPostfix.uid, + UID.SourceLangSwiftRef.functionOperatorPrefix.uid, + UID.SourceLangSwiftRef.functionSubscript.uid, + UID.SourceLangSwiftRef.generic_type_param.uid, + UID.SourceLangSwiftRef.module.uid, + UID.SourceLangSwiftRef.`precedencegroup`.uid, + UID.SourceLangSwiftRef.`protocol`.uid, + UID.SourceLangSwiftRef.`struct`.uid, + UID.SourceLangSwiftRef.`typealias`.uid, + UID.SourceLangSwiftRef.varClass.uid, + UID.SourceLangSwiftRef.varGlobal.uid, + UID.SourceLangSwiftRef.varInstance.uid, + UID.SourceLangSwiftRef.varLocal.uid, + UID.SourceLangSwiftRef.varStatic.uid, +] +fileprivate let knownUIDsOfSourceLangSwiftStmt: Set = [ + UID.SourceLangSwiftStmt.brace.uid, + UID.SourceLangSwiftStmt.`case`.uid, + UID.SourceLangSwiftStmt.`for`.uid, + UID.SourceLangSwiftStmt.foreach.uid, + UID.SourceLangSwiftStmt.`guard`.uid, + UID.SourceLangSwiftStmt.`if`.uid, + UID.SourceLangSwiftStmt.repeatwhile.uid, + UID.SourceLangSwiftStmt.`switch`.uid, + UID.SourceLangSwiftStmt.`while`.uid, +] +fileprivate let knownUIDsOfSourceLangSwiftStructureElem: Set = [ + UID.SourceLangSwiftStructureElem.condition_expr.uid, + UID.SourceLangSwiftStructureElem.expr.uid, + UID.SourceLangSwiftStructureElem.id.uid, + UID.SourceLangSwiftStructureElem.init_expr.uid, + UID.SourceLangSwiftStructureElem.pattern.uid, + UID.SourceLangSwiftStructureElem.typeref.uid, +] +fileprivate let knownUIDsOfSourceLangSwiftSyntaxtype: Set = [ + UID.SourceLangSwiftSyntaxtype.argument.uid, + UID.SourceLangSwiftSyntaxtype.attributeBuiltin.uid, + UID.SourceLangSwiftSyntaxtype.attributeId.uid, + UID.SourceLangSwiftSyntaxtype.buildconfigId.uid, + UID.SourceLangSwiftSyntaxtype.buildconfigKeyword.uid, + UID.SourceLangSwiftSyntaxtype.comment.uid, + UID.SourceLangSwiftSyntaxtype.commentMark.uid, + UID.SourceLangSwiftSyntaxtype.commentUrl.uid, + UID.SourceLangSwiftSyntaxtype.doccomment.uid, + UID.SourceLangSwiftSyntaxtype.doccommentField.uid, + UID.SourceLangSwiftSyntaxtype.identifier.uid, + UID.SourceLangSwiftSyntaxtype.keyword.uid, + UID.SourceLangSwiftSyntaxtype.number.uid, + UID.SourceLangSwiftSyntaxtype.objectliteral.uid, + UID.SourceLangSwiftSyntaxtype.parameter.uid, + UID.SourceLangSwiftSyntaxtype.placeholder.uid, + UID.SourceLangSwiftSyntaxtype.string.uid, + UID.SourceLangSwiftSyntaxtype.string_interpolation_anchor.uid, + UID.SourceLangSwiftSyntaxtype.typeidentifier.uid, +] +fileprivate let knownUIDsOfSourceNotification: Set = [ + UID.SourceNotification.editorDocumentupdate.uid, + UID.SourceNotification.sema_disabled.uid, +] +fileprivate let knownUIDsOfSourceRequest: Set = [ + UID.SourceRequest.buildsettingsRegister.uid, + UID.SourceRequest.codecomplete.uid, + UID.SourceRequest.codecompleteCacheOndisk.uid, + UID.SourceRequest.codecompleteClose.uid, + UID.SourceRequest.codecompleteOpen.uid, + UID.SourceRequest.codecompleteSetcustom.uid, + UID.SourceRequest.codecompleteSetpopularapi.uid, + UID.SourceRequest.codecompleteUpdate.uid, + UID.SourceRequest.crash_exit.uid, + UID.SourceRequest.cursorinfo.uid, + UID.SourceRequest.demangle.uid, + UID.SourceRequest.docinfo.uid, + UID.SourceRequest.editorClose.uid, + UID.SourceRequest.editorExpand_Placeholder.uid, + UID.SourceRequest.editorExtractComment.uid, + UID.SourceRequest.editorFind_Interface_Doc.uid, + UID.SourceRequest.editorFind_Usr.uid, + UID.SourceRequest.editorFormattext.uid, + UID.SourceRequest.editorOpen.uid, + UID.SourceRequest.editorOpenInterface.uid, + UID.SourceRequest.editorOpenInterfaceHeader.uid, + UID.SourceRequest.editorOpenInterfaceSwiftsource.uid, + UID.SourceRequest.editorOpenInterfaceSwifttype.uid, + UID.SourceRequest.editorReplacetext.uid, + UID.SourceRequest.indexsource.uid, + UID.SourceRequest.mangle_simple_class.uid, + UID.SourceRequest.moduleGroups.uid, + UID.SourceRequest.protocol_version.uid, + UID.SourceRequest.rangeinfo.uid, + UID.SourceRequest.relatedidents.uid, +] +let knownUIDsSets: [Set] = [ + knownUIDsOfKey, + knownUIDsOfSourceAvailabilityPlatform, + knownUIDsOfSourceCodecompletion, + knownUIDsOfSourceDeclAttribute, + knownUIDsOfSourceDiagnosticSeverity, + knownUIDsOfSourceDiagnosticStageSwift, + knownUIDsOfSourceLangSwift, + knownUIDsOfSourceLangSwiftAccessibility, + knownUIDsOfSourceLangSwiftAttribute, + knownUIDsOfSourceLangSwiftCodecomplete, + knownUIDsOfSourceLangSwiftDecl, + knownUIDsOfSourceLangSwiftExpr, + knownUIDsOfSourceLangSwiftImportModule, + knownUIDsOfSourceLangSwiftKeyword, + knownUIDsOfSourceLangSwiftLiteral, + knownUIDsOfSourceLangSwiftRef, + knownUIDsOfSourceLangSwiftStmt, + knownUIDsOfSourceLangSwiftStructureElem, + knownUIDsOfSourceLangSwiftSyntaxtype, + knownUIDsOfSourceNotification, + knownUIDsOfSourceRequest, + knownUIDsOfCustomKey, +] diff --git a/Source/SourceKittenFramework/UIDNamespace.swift b/Source/SourceKittenFramework/UIDNamespace.swift new file mode 100644 index 000000000..d1e0a79ec --- /dev/null +++ b/Source/SourceKittenFramework/UIDNamespace.swift @@ -0,0 +1,61 @@ +// +// UIDNamespace.swift +// SourceKitten +// +// Created by Norio Nomura on 10/22/16. +// Copyright © 2016 SourceKitten. All rights reserved. +// + +import Foundation +#if SWIFT_PACKAGE + import SourceKit +#endif + +// MARK: - UIDNamespace +public protocol UIDNamespace: CustomStringConvertible, Equatable, ExpressibleByStringLiteral, SourceKitObjectConvertible { + var uid: UID { get } + static var __uid_prefix: String { get } // swiftlint:disable:this variable_name +} + +extension UIDNamespace { + static func _inferUID(from string: String) -> UID { // swiftlint:disable:this identifier_name + let namespace = __uid_prefix + let fullyQualifiedName: String + if string.hasPrefix(".") { + fullyQualifiedName = namespace + string + } else { + // Check string begins with targeting namespace if DEBUG. + #if DEBUG + precondition(string.hasPrefix(namespace + "."), "string must begin with \"\(namespace).\".") + #endif + fullyQualifiedName = string + } + let result = UID(fullyQualifiedName) + return result + } + + // MARK: CustomStringConvertible + public var description: String { + return uid.description + } + + // MARK: ExpressibleByStringLiteral + // + // FIXME: Use following implementation when https://bugs.swift.org/browse/SR-3173 will be resolved. + /* + public init(stringLiteral value: String) { + self.init(uid: UID(value)) + } + public init(unicodeScalarLiteral value: String) { + self.init(uid: UID(value)) + } + public init(extendedGraphemeClusterLiteral value: String) { + self.init(uid: UID(value)) + } + */ + + // MARK: SourceKitObjectConvertible + public var object: sourcekitd_object_t? { + return sourcekitd_request_uid_create(uid.uid) + } +} diff --git a/Source/sourcekitten/CompleteCommand.swift b/Source/sourcekitten/CompleteCommand.swift index 5f85b1d02..2e8859e6a 100644 --- a/Source/sourcekitten/CompleteCommand.swift +++ b/Source/sourcekitten/CompleteCommand.swift @@ -66,9 +66,13 @@ struct CompleteCommand: CommandProtocol { } let request = Request.codeCompletionRequest(file: path, contents: contents, - offset: Int64(options.offset), + offset: options.offset, arguments: args) - print(CodeCompletionItem.parse(response: request.send())) - return .success() + do { + print(CodeCompletionItem.parse(response: try request.failableSend())) + return .success() + } catch { + return .failure(.failed(error)) + } } } diff --git a/Source/sourcekitten/Errors.swift b/Source/sourcekitten/Errors.swift index 7501d16cd..d1463c5e5 100644 --- a/Source/sourcekitten/Errors.swift +++ b/Source/sourcekitten/Errors.swift @@ -17,6 +17,9 @@ enum SourceKittenError: Error, CustomStringConvertible { /// Failed to generate documentation. case docFailed + /// failed with Error + case failed(Swift.Error) + /// An error message corresponding to this error. var description: String { switch self { @@ -26,6 +29,8 @@ enum SourceKittenError: Error, CustomStringConvertible { return "Failed to read file at '\(path)'" case .docFailed: return "Failed to generate documentation" + case let .failed(error): + return error.localizedDescription } } } diff --git a/Source/sourcekitten/FormatCommand.swift b/Source/sourcekitten/FormatCommand.swift index 500e8dbf8..9d7c36318 100644 --- a/Source/sourcekitten/FormatCommand.swift +++ b/Source/sourcekitten/FormatCommand.swift @@ -40,12 +40,16 @@ struct FormatCommand: CommandProtocol { guard !options.file.isEmpty else { return .failure(.invalidArgument(description: "file must be set when calling format")) } - try! File(path: options.file)? - .format(trimmingTrailingWhitespace: options.trimWhitespace, - useTabs: options.useTabs, - indentWidth: options.indentWidth) - .data(using: .utf8)? - .write(to: URL(fileURLWithPath: options.file), options: []) - return .success() + do { + try File(path: options.file)? + .format(trimmingTrailingWhitespace: options.trimWhitespace, + useTabs: options.useTabs, + indentWidth: options.indentWidth) + .data(using: .utf8)? + .write(to: URL(fileURLWithPath: options.file), options: []) + return .success() + } catch { + return .failure(.failed(error)) + } } } diff --git a/Source/sourcekitten/IndexCommand.swift b/Source/sourcekitten/IndexCommand.swift index 053943aa7..2579cd874 100644 --- a/Source/sourcekitten/IndexCommand.swift +++ b/Source/sourcekitten/IndexCommand.swift @@ -39,7 +39,11 @@ struct IndexCommand: CommandProtocol { } let absoluteFile = options.file.bridge().absolutePathRepresentation() let request = Request.index(file: absoluteFile, arguments: options.compilerargs.components(separatedBy: " ")) - print(toJSON(toNSDictionary(request.send()))) - return .success() + do { + print(toJSON(try request.failableSend().any)) + return .success() + } catch { + return .failure(.failed(error)) + } } } diff --git a/Source/sourcekitten/StructureCommand.swift b/Source/sourcekitten/StructureCommand.swift index 0bc03eef3..4e008f857 100644 --- a/Source/sourcekitten/StructureCommand.swift +++ b/Source/sourcekitten/StructureCommand.swift @@ -33,19 +33,23 @@ struct StructureCommand: CommandProtocol { } func run(_ options: Options) -> Result<(), SourceKittenError> { - if !options.file.isEmpty { - if let file = File(path: options.file) { - print(Structure(file: file)) + do { + if !options.file.isEmpty { + if let file = File(path: options.file) { + print(try Structure(file: file)) + return .success() + } + return .failure(.readFailed(path: options.file)) + } + if !options.text.isEmpty { + print(try Structure(file: File(contents: options.text))) return .success() } - return .failure(.readFailed(path: options.file)) - } - if !options.text.isEmpty { - print(Structure(file: File(contents: options.text))) - return .success() + return .failure( + .invalidArgument(description: "either file or text must be set when calling structure") + ) + } catch { + return .failure(.failed(error)) } - return .failure( - .invalidArgument(description: "either file or text must be set when calling structure") - ) } } diff --git a/Source/sourcekitten/SyntaxCommand.swift b/Source/sourcekitten/SyntaxCommand.swift index d3a85075d..5ad3a1aa1 100644 --- a/Source/sourcekitten/SyntaxCommand.swift +++ b/Source/sourcekitten/SyntaxCommand.swift @@ -33,14 +33,18 @@ struct SyntaxCommand: CommandProtocol { } func run(_ options: Options) -> Result<(), SourceKittenError> { - if !options.file.isEmpty { - if let file = File(path: options.file) { - print(SyntaxMap(file: file)) - return .success() + do { + if !options.file.isEmpty { + if let file = File(path: options.file) { + print(try SyntaxMap(file: file)) + return .success() + } + return .failure(.readFailed(path: options.file)) } - return .failure(.readFailed(path: options.file)) + print(try SyntaxMap(file: File(contents: options.text))) + return .success() + } catch { + return .failure(.failed(error)) } - print(SyntaxMap(file: File(contents: options.text))) - return .success() } } diff --git a/Source/sourcekitten/YamlRequestCommand.swift b/Source/sourcekitten/YamlRequestCommand.swift index 308a19aa2..062f0013e 100644 --- a/Source/sourcekitten/YamlRequestCommand.swift +++ b/Source/sourcekitten/YamlRequestCommand.swift @@ -41,7 +41,11 @@ struct RequestCommand: CommandProtocol { } let request = Request.yamlRequest(yaml: yaml) - print(toJSON(toNSDictionary(request.send()))) - return .success() + do { + print(toJSON(try request.failableSend().any)) + return .success() + } catch { + return .failure(.failed(error)) + } } } diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index 7e18fd776..dc391582e 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -9,6 +9,7 @@ XCTMain([ testCase(ModuleTests.allTests), testCase(OffsetMapTests.allTests), testCase(SourceKitTests.allTests), + testCase(SourceKitVariantTests.allTests), testCase(StringTests.allTests), testCase(StructureTests.allTests), testCase(SwiftDocsTests.allTests), diff --git a/Tests/SourceKittenFrameworkTests/CodeCompletionTests.swift b/Tests/SourceKittenFrameworkTests/CodeCompletionTests.swift index 3b6918a96..a2a4ba23b 100644 --- a/Tests/SourceKittenFrameworkTests/CodeCompletionTests.swift +++ b/Tests/SourceKittenFrameworkTests/CodeCompletionTests.swift @@ -15,8 +15,8 @@ class CodeCompletionTests: XCTestCase { func testSimpleCodeCompletion() { let file = "\(NSUUID().uuidString).swift" let completionItems = CodeCompletionItem.parse(response: - Request.codeCompletionRequest(file: file, contents: "0.", offset: 2, - arguments: ["-c", file, "-sdk", sdkPath()]).send()) + try! Request.codeCompletionRequest(file: file, contents: "0.", offset: 2, + arguments: ["-c", file, "-sdk", sdkPath()]).failableSend()) compareJSONString(withFixtureNamed: "SimpleCodeCompletion", jsonString: completionItems) } diff --git a/Tests/SourceKittenFrameworkTests/DocInfoTests.swift b/Tests/SourceKittenFrameworkTests/DocInfoTests.swift index 425ae42c9..6d5e044a5 100644 --- a/Tests/SourceKittenFrameworkTests/DocInfoTests.swift +++ b/Tests/SourceKittenFrameworkTests/DocInfoTests.swift @@ -15,24 +15,19 @@ class DocInfoTests: XCTestCase { /// Validates that various doc string formats are parsed correctly. func testDocInfoRequest() { let swiftFile = File(path: fixturesDirectory + "DocInfo.swift")! - let info = toNSDictionary( - Request.docInfo(text: swiftFile.contents, - arguments: ["-sdk", sdkPath()]).send() - ) - compareJSONString(withFixtureNamed: "DocInfo", jsonString: toJSON(info)) + let info = try! Request.docInfo(text: swiftFile.contents, + arguments: ["-sdk", sdkPath()]).failableSend() + compareJSONString(withFixtureNamed: "DocInfo", jsonString: toJSON(info.any)) } func testModuleInfoRequest() { let swiftFile = fixturesDirectory + "DocInfo.swift" - let info = toNSDictionary( - Request.moduleInfo(module: "", - arguments: [ - "-c", swiftFile, - "-module-name", "DocInfo", - "-sdk", sdkPath() - ]).send() - ) - compareJSONString(withFixtureNamed: "ModuleInfo", jsonString: toJSON(info)) + let info = try! Request.moduleInfo(module: "", + arguments: [ + "-c", swiftFile, + "-module-name", "DocInfo", + "-sdk", sdkPath()]).failableSend() + compareJSONString(withFixtureNamed: "ModuleInfo", jsonString: toJSON(info.any)) } } diff --git a/Tests/SourceKittenFrameworkTests/FileTests.swift b/Tests/SourceKittenFrameworkTests/FileTests.swift index b7514038d..54ec8736f 100644 --- a/Tests/SourceKittenFrameworkTests/FileTests.swift +++ b/Tests/SourceKittenFrameworkTests/FileTests.swift @@ -21,7 +21,7 @@ class FileTests: XCTestCase { print("FIXME: Skip \(#function), because our sourcekitInProc on Swift 3.1 for Linux seems to be broken") #else let file = File(path: fixturesDirectory + "BicycleUnformatted.swift") - let formattedFile = file?.format(trimmingTrailingWhitespace: true, + let formattedFile = try! file?.format(trimmingTrailingWhitespace: true, useTabs: false, indentWidth: 4) XCTAssertEqual(formattedFile!, try! String(contentsOfFile: fixturesDirectory + "Bicycle.swift", encoding: .utf8)) diff --git a/Tests/SourceKittenFrameworkTests/OffsetMapTests.swift b/Tests/SourceKittenFrameworkTests/OffsetMapTests.swift index bdf31aa48..c86ffbc54 100644 --- a/Tests/SourceKittenFrameworkTests/OffsetMapTests.swift +++ b/Tests/SourceKittenFrameworkTests/OffsetMapTests.swift @@ -22,8 +22,8 @@ class OffsetMapTests: XCTestCase { "struct VoidStruct {\n/// Returns or sets Void.\nsubscript(key: String) -> () {\n" + "get { return () }\nset {}\n}\n}" ) - let documentedTokenOffsets = file.contents.documentedTokenOffsets(syntaxMap: SyntaxMap(file: file)) - let response = file.process(dictionary: Request.editorOpen(file: file).send(), cursorInfoRequest: nil) + let documentedTokenOffsets = file.contents.documentedTokenOffsets(syntaxMap: try! SyntaxMap(file: file)) + let response = file.process(dictionary: try! Request.editorOpen(file: file).failableSend(), cursorInfoRequest: nil) let offsetMap = file.makeOffsetMap(documentedTokenOffsets: documentedTokenOffsets, dictionary: response) XCTAssertEqual(offsetMap, [46: 7], "should generate correct offset map of [(declaration offset): (parent offset)]") #endif @@ -36,8 +36,8 @@ class OffsetMapTests: XCTestCase { #else // Struct declarations are parsed by SourceKit, so OffsetMap shouldn't contain its offset. let file = File(contents: "/// Doc Comment\nstruct DocumentedStruct {}") - let documentedTokenOffsets = file.contents.documentedTokenOffsets(syntaxMap: SyntaxMap(file: file)) - let response = file.process(dictionary: Request.editorOpen(file: file).send(), cursorInfoRequest: nil) + let documentedTokenOffsets = file.contents.documentedTokenOffsets(syntaxMap: try! SyntaxMap(file: file)) + let response = file.process(dictionary: try! Request.editorOpen(file: file).failableSend(), cursorInfoRequest: nil) let offsetMap = file.makeOffsetMap(documentedTokenOffsets: documentedTokenOffsets, dictionary: response) XCTAssertEqual(offsetMap, [:], "should generate empty offset map") #endif diff --git a/Tests/SourceKittenFrameworkTests/SourceKitObjectTests.swift b/Tests/SourceKittenFrameworkTests/SourceKitObjectTests.swift new file mode 100644 index 000000000..5ce883d65 --- /dev/null +++ b/Tests/SourceKittenFrameworkTests/SourceKitObjectTests.swift @@ -0,0 +1,30 @@ +// +// SourceKitObjectTests.swift +// SourceKitten +// +// Created by 野村 憲男 on 11/29/16. +// Copyright © 2016 SourceKitten. All rights reserved. +// + +import XCTest +@testable import SourceKittenFramework + +class SourceKitObjectTests: XCTestCase { + + func testExample() { + let path = #file + let object: SourceKitObject = [ + .request: UID.SourceRequest.editorOpen, + "key.name": path, + "key.sourcefile": path + ] + let expected = [ + "{", + " key.request: source.request.editor.open,", + " key.name: \"\(#file)\",", + " key.sourcefile: \"\(#file)\"", + "}" + ].joined(separator: "\n") + XCTAssertEqual(object.description, expected) + } +} diff --git a/Tests/SourceKittenFrameworkTests/SourceKitTests.swift b/Tests/SourceKittenFrameworkTests/SourceKitTests.swift index 0df56bbab..60e1ccc91 100644 --- a/Tests/SourceKittenFrameworkTests/SourceKitTests.swift +++ b/Tests/SourceKittenFrameworkTests/SourceKitTests.swift @@ -171,7 +171,7 @@ class SourceKitTests: XCTestCase { for (module, path, linuxPath, spmModule) in modules { let wrapperPath = "\(projectRoot)/Source/SourceKittenFramework/library_wrapper_\(module).swift" let existingWrapper = try! String(contentsOfFile: wrapperPath) - let generatedWrapper = libraryWrapperForModule(module, loadPath: path, linuxPath: linuxPath, spmModule: spmModule, + let generatedWrapper = try! libraryWrapperForModule(module, loadPath: path, linuxPath: linuxPath, spmModule: spmModule, compilerArguments: sourceKittenFrameworkModule.compilerArguments) XCTAssertEqual(existingWrapper, generatedWrapper) let overwrite = false // set this to true to overwrite existing wrappers with the generated ones @@ -184,7 +184,7 @@ class SourceKitTests: XCTestCase { func testIndex() { let file = "\(fixturesDirectory)Bicycle.swift" let arguments = ["-sdk", sdkPath(), "-j4", file ] - let indexJSON = NSMutableString(string: toJSON(toNSDictionary(Request.index(file: file, arguments: arguments).send())) + "\n") + let indexJSON = NSMutableString(string: toJSON(try! Request.index(file: file, arguments: arguments).failableSend().any) + "\n") func replace(_ pattern: String, withTemplate template: String) { let regex = try! NSRegularExpression(pattern: pattern, options: []) @@ -207,10 +207,14 @@ class SourceKitTests: XCTestCase { #else let path = fixturesDirectory + "Subscript.swift" let yaml = "key.request: source.request.editor.open\nkey.name: \"\(path)\"\nkey.sourcefile: \"\(path)\"" - let output = Request.yamlRequest(yaml: yaml).send() - let expectedStructure = Structure(file: File(path: path)!) - let actualStructure = Structure(sourceKitResponse: output) - XCTAssertEqual(expectedStructure, actualStructure) + do { + let output = try Request.yamlRequest(yaml: yaml).failableSend() + let expectedStructure = try Structure(file: File(path: path)!) + let actualStructure = Structure(sourceKitVariant: output) + XCTAssertEqual(expectedStructure, actualStructure) + } catch { + XCTFail("\(error)") + } #endif } } diff --git a/Tests/SourceKittenFrameworkTests/SourceKitVariantTests.swift b/Tests/SourceKittenFrameworkTests/SourceKitVariantTests.swift new file mode 100644 index 000000000..71c66386d --- /dev/null +++ b/Tests/SourceKittenFrameworkTests/SourceKitVariantTests.swift @@ -0,0 +1,218 @@ +// +// SourceKitVariantTests.swift +// SourceKitten +// +// Created by Norio Nomura on 11/28/16. +// Copyright (c) 2016 SourceKitten. All rights reserved. +// + +import XCTest +@testable import SourceKittenFramework + +class SourceKitVariantTests: XCTestCase { + + func testSupportArray() { + // Initializer + let variant = SourceKitVariant(["foo", true, 1]) + + // Property + XCTAssertEqual(variant.array!, ["foo", true, 1]) + XCTAssertNotEqual(variant.array!, ["bar", true, 1]) + + // ExpressibleByArrayLiteral + XCTAssertEqual(variant, ["foo", true, 1]) + XCTAssertNotEqual(variant, ["bar", true, 1]) + + // Any + XCTAssertTrue(variant.any is [Any]) + XCTAssertFalse(variant.any is Bool) + XCTAssertFalse(variant.any is [String:Any]) + XCTAssertFalse(variant.any is Int) + XCTAssertFalse(variant.any is String) + + // Subscript + XCTAssertEqual(variant[0], "foo") + XCTAssertEqual(variant[1], true) + XCTAssertEqual(variant[2], 1) + + // Mutation + var mutable = variant + mutable.array = ["bar", true, 1] + XCTAssertNotEqual(mutable, ["foo", true, 1]) + XCTAssertEqual(mutable, ["bar", true, 1]) + mutable[0] = "baz" + mutable[1] = false + mutable[2] = 2 + XCTAssertEqual(mutable, ["baz", false, 2]) + + // Copy on write + XCTAssertNotEqual(mutable, variant) + } + + func testSupportBool() { + // Initializer + let variant = SourceKitVariant(true) + + // Property + XCTAssertEqual(variant.bool, true) + XCTAssertNotEqual(variant.bool, false) + + // ExpressibleByBooleanLiteral + XCTAssertEqual(variant, true) + XCTAssertNotEqual(variant, false) + + // Any + XCTAssertFalse(variant.any is [Any]) + XCTAssertTrue(variant.any is Bool) + XCTAssertFalse(variant.any is [String:Any]) + XCTAssertFalse(variant.any is Int) + XCTAssertFalse(variant.any is String) + + // Mutation + var mutable = variant + mutable.bool = false + XCTAssertNotEqual(mutable.bool, true) + XCTAssertEqual(mutable.bool, false) + + // Copy on write + XCTAssertNotEqual(mutable, variant) + } + + func testSupportDictionary() { + // Initializer + let variant = SourceKitVariant(["key.request": "foo"]) + + // Property + XCTAssertEqual(variant.dictionary!, ["key.request": "foo"]) + XCTAssertNotEqual(variant.dictionary!, ["key.request": "bar"]) + + // ExpressibleByDictionaryLiteral + XCTAssertEqual(variant, ["key.request": "foo"]) + XCTAssertNotEqual(variant, ["key.request": "bar"]) + + // Any + XCTAssertFalse(variant.any is [Any]) + XCTAssertFalse(variant.any is Bool) + XCTAssertTrue(variant.any is [String:Any]) + XCTAssertFalse(variant.any is Int) + XCTAssertFalse(variant.any is String) + + // Subscript + XCTAssertEqual(variant["key.request"], "foo") + XCTAssertNil(variant["key.name"]) + + // mutation + var mutable = variant + mutable.dictionary = ["key.request": "bar"] + XCTAssertNotEqual(mutable, ["key.request": "foo"]) + XCTAssertEqual(mutable, ["key.request": "bar"]) + + // Copy on write + XCTAssertNotEqual(mutable, variant) + + // remove value + var removable = variant + removable.removeValue(forKey: "key.request") + XCTAssertNotEqual(removable, ["key.request": "foo"]) + XCTAssertEqual(removable, [:]) + + // Copy on write + XCTAssertNotEqual(removable, variant) + } + + func testSupportInteger() { + // Initializer + let variant = SourceKitVariant(1) + + // Property + XCTAssertEqual(variant.int, 1) + XCTAssertNotEqual(variant.int, 2) + + // ExpressibleByIntegerLiteral + XCTAssertEqual(variant, 1) + XCTAssertNotEqual(variant, 2) + + // Any + XCTAssertFalse(variant.any is [Any]) + XCTAssertFalse(variant.any is Bool) + XCTAssertFalse(variant.any is [String:Any]) + XCTAssertTrue(variant.any is Int) + XCTAssertFalse(variant.any is String) + + // Mutation + var mutable = variant + mutable.int = 2 + XCTAssertNotEqual(mutable.int, 1) + XCTAssertEqual(mutable.int, 2) + + // Copy on write + XCTAssertNotEqual(mutable, variant) + } + + func testSupportString() { + // Initializer + let variant = SourceKitVariant("foo") + + // Property + XCTAssertEqual(variant.string, "foo") + XCTAssertNotEqual(variant.string, "bar") + + // ExpressibleByStringLiteral + XCTAssertEqual(variant, "foo") + XCTAssertNotEqual(variant, "bar") + + // Any + XCTAssertFalse(variant.any is [Any]) + XCTAssertFalse(variant.any is Bool) + XCTAssertFalse(variant.any is [String:Any]) + XCTAssertFalse(variant.any is Int) + XCTAssertTrue(variant.any is String) + + // Mutation + var mutable = variant + mutable.string = "bar" + XCTAssertNotEqual(mutable.string, "foo") + XCTAssertEqual(mutable.string, "bar") + + // Copy on write + XCTAssertNotEqual(mutable, variant) + } + + func testUID() { + // Initializer + let variant = SourceKitVariant(UID("key.request")) + + // Property + XCTAssertEqual(variant.uid, UID("key.request")) + XCTAssertNotEqual(variant.uid, UID("key.name")) + + // Any + XCTAssertFalse(variant.any is [Any]) + XCTAssertFalse(variant.any is Bool) + XCTAssertFalse(variant.any is [String:Any]) + XCTAssertFalse(variant.any is Int) + XCTAssertTrue(variant.any is String) + + // Mutation + var mutable = variant + mutable.uid = UID("key.name") + XCTAssertNotEqual(mutable.uid, UID("key.request")) + XCTAssertEqual(mutable.uid, UID("key.name")) + + // Copy on write + XCTAssertNotEqual(mutable, variant) + } +} + +extension SourceKitVariantTests { + static var allTests: [(String, (SourceKitVariantTests) -> () throws -> Void)] { + return [ + ("testSupportArray", testSupportArray), + ("testSupportBool", testSupportBool), + ("testSupportDictionary", testSupportDictionary), + ("testSupportInteger", testSupportInteger), + ("testSupportString", testSupportString), + ("testUID", testUID) + ] + } +} diff --git a/Tests/SourceKittenFrameworkTests/StringTests.swift b/Tests/SourceKittenFrameworkTests/StringTests.swift index 01c935ff9..32a67aa08 100644 --- a/Tests/SourceKittenFrameworkTests/StringTests.swift +++ b/Tests/SourceKittenFrameworkTests/StringTests.swift @@ -90,21 +90,21 @@ class StringTests: XCTestCase { print("FIXME: Skip \(#function), because our sourcekitInProc on Swift 3.1 for Linux seems to be broken") #else let source = "struct A { subscript(key: String) -> Void { return () } }" - let actual = SyntaxMap(file: File(contents: source)).tokens.filter(source.isTokenDocumentable) + let actual = try! SyntaxMap(file: File(contents: source)).tokens.filter(source.isTokenDocumentable) let expected = [ - SyntaxToken(type: SyntaxKind.identifier.rawValue, offset: 7, length: 1), // `A` - SyntaxToken(type: SyntaxKind.keyword.rawValue, offset: 11, length: 9), // `subscript` - SyntaxToken(type: SyntaxKind.identifier.rawValue, offset: 21, length: 3) // `key` + SyntaxToken(type: .identifier, offset: 7, length: 1), // `A` + SyntaxToken(type: .keyword, offset: 11, length: 9), // `subscript` + SyntaxToken(type: .identifier, offset: 21, length: 3) // `key` ] XCTAssertEqual(actual, expected, "should detect documentable tokens") #endif } func testParseDeclaration() { - let dict: [String: SourceKitRepresentable] = [ + let dict: SourceKitVariant = [ "key.kind": "source.lang.swift.decl.class", - "key.offset": Int64(24), - "key.bodyoffset": Int64(32), + "key.offset": 24, + "key.bodyoffset": 32, "key.annotated_decl": "", "key.typename": "ClassA.Type" ] @@ -119,7 +119,7 @@ class StringTests: XCTestCase { print("FIXME: Skip \(#function), because our sourcekitInProc on Swift 3.1 for Linux seems to be broken") #else let fileContents = "/// Comment\nlet global = 0" - let syntaxMap = SyntaxMap(file: File(contents: fileContents)) + let syntaxMap = try! SyntaxMap(file: File(contents: fileContents)) XCTAssertEqual(fileContents.documentedTokenOffsets(syntaxMap: syntaxMap), [16], "should generate documented token offsets") #endif } @@ -130,7 +130,7 @@ class StringTests: XCTestCase { print("FIXME: Skip \(#function), because our sourcekitInProc on Swift 3.1 for Linux seems to be broken") #else let file = File(path: fixturesDirectory + "Subscript.swift")! - let syntaxMap = SyntaxMap(file: file) + let syntaxMap = try! SyntaxMap(file: file) XCTAssertEqual(file.contents.documentedTokenOffsets(syntaxMap: syntaxMap), [54], "should generate documented token offsets") #endif } @@ -141,7 +141,7 @@ class StringTests: XCTestCase { print("FIXME: Skip \(#function), because our sourcekitInProc on Swift 3.1 for Linux seems to be broken") #else let fileContents = "// Comment\nlet global = 0" - let syntaxMap = SyntaxMap(file: File(contents: fileContents)) + let syntaxMap = try! SyntaxMap(file: File(contents: fileContents)) XCTAssertEqual(fileContents.documentedTokenOffsets(syntaxMap: syntaxMap).count, 0, "shouldn't detect any documented token offsets when there are none") #endif } diff --git a/Tests/SourceKittenFrameworkTests/StructureTests.swift b/Tests/SourceKittenFrameworkTests/StructureTests.swift index 45e789304..09ca3256b 100644 --- a/Tests/SourceKittenFrameworkTests/StructureTests.swift +++ b/Tests/SourceKittenFrameworkTests/StructureTests.swift @@ -31,8 +31,8 @@ class StructureTests: XCTestCase { "key.diagnostic_stage": "source.diagnostic.stage.swift.parse" ] #endif - let structure = Structure(file: File(contents: "")) - XCTAssertEqual(toNSDictionary(structure.dictionary), expected, "should generate expected structure") + let structure = try! Structure(file: File(contents: "")) + XCTAssertEqual(structure.dictionary, expected, "should generate expected structure") #endif } @@ -42,7 +42,7 @@ class StructureTests: XCTestCase { print("FIXME: Skip \(#function), because our sourcekitInProc on Swift 3.1 for Linux seems to be broken") #else let fileContents = try! String(contentsOfFile: #file, encoding: .utf8) - XCTAssertEqual(Structure(file: File(path: #file)!), + try! XCTAssertEqual(Structure(file: File(path: #file)!), Structure(file: File(contents: fileContents)), "should generate the same structure for a file as raw text") #endif @@ -53,7 +53,7 @@ class StructureTests: XCTestCase { // FIXME print("FIXME: Skip \(#function), because our sourcekitInProc on Swift 3.1 for Linux seems to be broken") #else - let structure = Structure(file: File(contents: "enum MyEnum { case First }")) + let structure = try! Structure(file: File(contents: "enum MyEnum { case First }")) let expectedStructure: NSDictionary = [ "key.substructure": [ [ @@ -92,7 +92,7 @@ class StructureTests: XCTestCase { "key.diagnostic_stage": "source.diagnostic.stage.swift.parse", "key.length": 26 ] - XCTAssertEqual(toNSDictionary(structure.dictionary), expectedStructure, "should generate expected structure") + XCTAssertEqual(structure.dictionary, expectedStructure, "should generate expected structure") #endif } @@ -101,7 +101,7 @@ class StructureTests: XCTestCase { // FIXME print("FIXME: Skip \(#function), because our sourcekitInProc on Swift 3.1 for Linux seems to be broken") #else - let structure = Structure(file: File(contents: "struct A { func b() {} }")) + let structure = try! Structure(file: File(contents: "struct A { func b() {} }")) let expectedStructure: NSDictionary = [ "key.substructure": [ [ @@ -133,10 +133,10 @@ class StructureTests: XCTestCase { "key.diagnostic_stage": "source.diagnostic.stage.swift.parse", "key.length": 24 ] - XCTAssertEqual(toNSDictionary(structure.dictionary), expectedStructure, "should generate expected structure") + XCTAssertEqual(structure.dictionary, expectedStructure, "should generate expected structure") let jsonData = structure.description.data(using: .utf8)! - let jsonDictionary = try! JSONSerialization.jsonObject(with: jsonData, options: []) as! [AnyHashable: Any] + let jsonDictionary = try! JSONSerialization.jsonObject(with: jsonData, options: []) as! [String:Any] XCTAssertEqual(jsonDictionary.bridge(), expectedStructure, "JSON should match expected structure") #endif } diff --git a/Tests/SourceKittenFrameworkTests/SwiftDocsTests.swift b/Tests/SourceKittenFrameworkTests/SwiftDocsTests.swift index a83371494..d9ea017eb 100644 --- a/Tests/SourceKittenFrameworkTests/SwiftDocsTests.swift +++ b/Tests/SourceKittenFrameworkTests/SwiftDocsTests.swift @@ -87,7 +87,7 @@ class SwiftDocsTests: XCTestCase { func testParseFullXMLDocs() { // swiftlint:disable:next line_length let xmlDocsString = "nameusrdeclarationdiscussionparam1inparam1_discussionresult_discussion" - let parsed = parseFullXMLDocs(xmlDocsString)! + let parsed = parseFullXMLDocs(xmlDocsString)?.any as! [String:Any] let expected: NSDictionary = [ "key.doc.type": "Type", "key.doc.file": "file", @@ -102,7 +102,7 @@ class SwiftDocsTests: XCTestCase { ]], "key.doc.result_discussion": [["Para": "result_discussion"]] ] - XCTAssertEqual(toNSDictionary(parsed), expected) + XCTAssertEqual(parsed.bridge(), expected) } } diff --git a/Tests/SourceKittenFrameworkTests/SyntaxTests.swift b/Tests/SourceKittenFrameworkTests/SyntaxTests.swift index a7bf40f78..8fe4f71c8 100644 --- a/Tests/SourceKittenFrameworkTests/SyntaxTests.swift +++ b/Tests/SourceKittenFrameworkTests/SyntaxTests.swift @@ -7,16 +7,16 @@ // import Foundation -import SourceKittenFramework +@testable import SourceKittenFramework import XCTest -private typealias TokenWrapper = (kind: SyntaxKind, offset: Int, length: Int) +private typealias TokenWrapper = (type: UID.SourceLangSwiftSyntaxtype, offset: Int, length: Int) private func compareSyntax(file: File, expectedTokens: [TokenWrapper]) { let expectedSyntaxMap = SyntaxMap(tokens: expectedTokens.map { tokenWrapper in - return SyntaxToken(type: tokenWrapper.kind.rawValue, offset: tokenWrapper.offset, length: tokenWrapper.length) + return SyntaxToken(type: tokenWrapper.type, offset: tokenWrapper.offset, length: tokenWrapper.length) }) - let syntaxMap = SyntaxMap(file: file) + let syntaxMap = try! SyntaxMap(file: file) XCTAssertEqual(syntaxMap, expectedSyntaxMap, "should generate expected syntax map") let syntaxJSONData = syntaxMap.description.data(using: .utf8)! @@ -35,7 +35,7 @@ class SyntaxTests: XCTestCase { // FIXME print("FIXME: Skip \(#function), because our sourcekitInProc on Swift 3.1 for Linux seems to be broken") #else - XCTAssertEqual(SyntaxMap(file: File(contents: "")).description, "[\n\n]", "should print empty syntax") + XCTAssertEqual(try! SyntaxMap(file: File(contents: "")).description, "[\n\n]", "should print empty syntax") #endif } @@ -45,7 +45,7 @@ class SyntaxTests: XCTestCase { print("FIXME: Skip \(#function), because our sourcekitInProc on Swift 3.1 for Linux seems to be broken") #else let fileContents = try! String(contentsOfFile: #file, encoding: .utf8) - XCTAssertEqual(SyntaxMap(file: File(path: #file)!), + try! XCTAssertEqual(SyntaxMap(file: File(path: #file)!), SyntaxMap(file: File(contents: fileContents)), "should generate the same syntax map for a file as raw text") #endif diff --git a/Tests/SourceKittenFrameworkTests/UIDNamespaceTests.swift b/Tests/SourceKittenFrameworkTests/UIDNamespaceTests.swift new file mode 100644 index 000000000..a1fc15224 --- /dev/null +++ b/Tests/SourceKittenFrameworkTests/UIDNamespaceTests.swift @@ -0,0 +1,335 @@ +// +// UIDNamespaceTests.swift +// SourceKitten +// +// Created by Norio Nomura on 10/22/16. +// Copyright (c) 2016 SourceKitten. All rights reserved. +// + +#if os(Linux) +import Glibc +#endif +import Foundation +import XCTest +@testable import SourceKittenFramework + +class UIDNamespaceTests: XCTestCase { + + func testExpressibleByStringLiteral() { + // Use Fully Qualified Name + let keyRequest: UID.Key = "key.request" + XCTAssertEqual(keyRequest, .request) + + // Use short name with infering prefix + let keyKind: UID.Key = ".kind" + XCTAssertEqual(UID.Key.kind, keyKind) + } + + func testCompareToSelf() { + // Equatable + XCTAssertEqual(UID.SourceLangSwiftDecl.extensionClass, ".extension.class") + XCTAssertNotEqual(UID.SourceLangSwiftDecl.extensionClass, ".extension.enum") + + // `==` operator + XCTAssertTrue(UID.SourceLangSwiftDecl.extensionClass == ".extension.class") + XCTAssertFalse(UID.SourceLangSwiftDecl.extensionClass == ".extension.enum") + + // `!=` operator + XCTAssertFalse(UID.SourceLangSwiftDecl.extensionClass != ".extension.class") + XCTAssertTrue(UID.SourceLangSwiftDecl.extensionClass != ".extension.enum") + } + + func testUseOperatorsForComparingToUID() { + let uidExtensionClass = UID("source.lang.swift.decl.extension.class") + let uidExtensionEnum = UID("source.lang.swift.decl.extension.enum") + + // `==` operator + XCTAssertTrue(UID.SourceLangSwiftDecl.extensionClass == uidExtensionClass) + XCTAssertFalse(UID.SourceLangSwiftDecl.extensionClass == uidExtensionEnum) + XCTAssertTrue(uidExtensionClass == UID.SourceLangSwiftDecl.extensionClass) + XCTAssertFalse(uidExtensionEnum == UID.SourceLangSwiftDecl.extensionClass) + + XCTAssertTrue(UID.SourceLangSwiftDecl.extensionClass == Optional(uidExtensionClass)) + XCTAssertFalse(UID.SourceLangSwiftDecl.extensionClass == Optional(uidExtensionEnum)) + XCTAssertTrue(Optional(uidExtensionClass) == UID.SourceLangSwiftDecl.extensionClass) + XCTAssertFalse(Optional(uidExtensionEnum) == UID.SourceLangSwiftDecl.extensionClass) + + // `!=` operator + XCTAssertFalse(UID.SourceLangSwiftDecl.extensionClass != uidExtensionClass) + XCTAssertTrue(UID.SourceLangSwiftDecl.extensionClass != uidExtensionEnum) + XCTAssertFalse(uidExtensionClass != UID.SourceLangSwiftDecl.extensionClass) + XCTAssertTrue(uidExtensionEnum != UID.SourceLangSwiftDecl.extensionClass) + + XCTAssertFalse(UID.SourceLangSwiftDecl.extensionClass != Optional(uidExtensionClass)) + XCTAssertTrue(UID.SourceLangSwiftDecl.extensionClass != Optional(uidExtensionEnum)) + XCTAssertFalse(Optional(uidExtensionClass) != UID.SourceLangSwiftDecl.extensionClass) + XCTAssertTrue(Optional(uidExtensionEnum) != UID.SourceLangSwiftDecl.extensionClass) + } + +// func testUnknownUIDCausesPreconditionFailureOnDebugBuild() { +// XCTAssertTrue(UID.Key.request == ".unknown") +// } + + func testUIDNamespaceAreUpToDate() { + guard let sourcekitdPath = loadedSourcekitdPath() else { + XCTFail("fail to get sourcekitd image path") + return + } + #if os(Linux) + let imagePaths = [sourcekitdPath] + #else + let imagePaths = [sourcekitdPath, getSourceKitServicePath(from: sourcekitdPath)] + #endif + guard let uidStrings = extractUIDStrings(from: imagePaths) else { + XCTFail("fail to get uid strings") + return + } + let generatedUIDNamespace = createExtensionOfUID(from: uidStrings) + let uidNamespacePath = "\(projectRoot)/Source/SourceKittenFramework/UIDNamespace+generated.swift" + let existingUIDNamespace = try! String(contentsOfFile: uidNamespacePath) + + XCTAssertEqual(existingUIDNamespace, generatedUIDNamespace) + + // set this to true to overwrite existing UIDNamespace+generated.swift with the generated ones + let overwrite = false + if existingUIDNamespace != generatedUIDNamespace && overwrite { + try! generatedUIDNamespace.data(using: .utf8)?.write(to: URL(fileURLWithPath: uidNamespacePath)) + } + } +} + +extension UIDNamespaceTests { + static var allTests: [(String, (UIDNamespaceTests) -> () throws -> Void)] { + return [ + ("testExpressibleByStringLiteral", testExpressibleByStringLiteral), + ("testCompareToSelf", testCompareToSelf), + ("testUseOperatorsForComparingToUID", testUseOperatorsForComparingToUID) +// ("testUnknownUIDCausesPreconditionFailureOnDebugBuild", testUnknownUIDCausesPreconditionFailureOnDebugBuild), + // FIXME: https://bugs.swift.org/browse/SR-3250 +// ("testUIDNamespaceAreUpToDate", testUIDNamespaceAreUpToDate), + ] + } +} + +// MARK: - testUIDNamespaceAreUpToDate helper + +fileprivate func loadedSourcekitdPath() -> String? { + #if os(Linux) + // FIXME: https://bugs.swift.org/browse/SR-3250 + fatalError() +// let library = toolchainLoader.load(path: "libsourcekitdInProc.so") +// let symbol = dlsym(library.handle, "sourcekitd_initialize") +// var info = dl_info() +// guard 0 != dladdr(symbol, &info) else { return nil } +// return String(cString: info.dli_fname) + #else + let library = toolchainLoader.load(path: "sourcekitd.framework/Versions/A/sourcekitd") + let symbol = dlsym(library.handle, "sourcekitd_initialize") + var info = dl_info() + guard 0 != dladdr(symbol, &info) else { return nil } + return String(cString: info.dli_fname) + #endif +} + +fileprivate func getSourceKitServicePath(from sourcekitdPath: String) -> String { + let component = "XPCServices/SourceKitService.xpc/Contents/MacOS/SourceKitService" + return URL(fileURLWithPath: sourcekitdPath) + .deletingLastPathComponent() + .deletingLastPathComponent() + .deletingLastPathComponent() + .appendingPathComponent(component) + .path +} + +fileprivate let tab = " " +fileprivate func indent(_ string: String) -> String { + return tab + string +} + +func extractUIDStrings(from images: [String]) -> [String]? { + let task = Process() + task.launchPath = "/usr/bin/strings" + task.arguments = images + let pipe = Pipe() + task.standardOutput = pipe + task.launch() + + let data = pipe.fileHandleForReading.readDataToEndOfFile() + guard let output = String(data: data, encoding: .utf8) else { + return nil + } + let uidStrings = output + .components(separatedBy: .newlines) + .filter { ($0.hasPrefix("source.") || $0.hasPrefix("key.")) && !$0.contains(" ") } + return Set(uidStrings).sorted() +} + +fileprivate let desiredTypes = [ + "key", + "source.availability.platform", + "source.codecompletion", + "source.decl.attribute", + "source.diagnostic.severity", + "source.diagnostic.stage.swift", + "source.lang.swift", + "source.lang.swift.accessibility", + "source.lang.swift.attribute", + "source.lang.swift.codecomplete", + "source.lang.swift.decl", + "source.lang.swift.expr", + "source.lang.swift.import.module", + "source.lang.swift.keyword", + "source.lang.swift.literal", + "source.lang.swift.ref", + "source.lang.swift.stmt", + "source.lang.swift.structure.elem", + "source.lang.swift.syntaxtype", + "source.notification", + "source.request" +] + +fileprivate func createExtensionOfUID(from uidStrings: [String]) -> String { + let keywordPrefix = "source.lang.swift.keyword." + Namespace.keywords = uidStrings + .filter { $0.hasPrefix(keywordPrefix) } + .map { $0.replacingOccurrences(of: keywordPrefix, with: "") } + + let namespaces = desiredTypes.sorted(by: >).map(Namespace.init) + uidStrings.forEach { uidString in + if !namespaces.contains { $0.append(child: uidString) } { + print("Unkown uid detected: \(uidString)") + } + } + + let sortedNamespaces = namespaces.sorted(by: { $0.name < $1.name }) + + var lines = [String]() + // enums + lines.append("extension UID {") + lines.append(contentsOf: sortedNamespaces.flatMap({ $0.renderEnum() }).map(indent)) + lines.append(contentsOf: ["}", ""]) + // extensions + lines.append(contentsOf: sortedNamespaces.flatMap { $0.renderExtension() }) + // isMemberPropertiesExtension + lines.append("extension UID {") + lines.append(contentsOf: sortedNamespaces.map({ $0.renderIsMemberProperty() }).map(indent)) + lines.append("}") + // knownUIDOfContents + lines.append(contentsOf: sortedNamespaces.flatMap { $0.renderKnownUIDOf() }) + // knownUIDs + lines.append("let knownUIDsSets: [Set] = [") + lines.append(contentsOf: sortedNamespaces.map({ "knownUIDsOf\($0.typeName)," }).map(indent)) + lines.append(indent("knownUIDsOfCustomKey,")) + lines.append("]") + + return lines.joined(separator: "\n") + "\n" +} + +fileprivate class Namespace { + let name: String + + static var keywords: [String] = [] + + init(name: String) { + self.name = name + } + + func append(child uidString: String) -> Bool { + if uidString.hasPrefix(name + ".") { + if !uidString.hasSuffix(".") { + children.append(uidString) + } + return true + } + return false + } + + func renderEnum() -> [String] { + var result = [String]() + result.append("public struct \(name.upperCamelCase) {") + result.append(indent("public let uid: UID")) + result.append(contentsOf: children.flatMap(render).map(indent)) + result.append("}") + return result + } + + func renderExtension() -> [String] { + var result = [String]() + result.append("extension UID.\(typeName): UIDNamespace {") + result.append(indent("public static let __uid_prefix = \"\(name)\"")) + result.append(contentsOf: renderMethods().map(indent)) + result.append("}") + return result + } + + func renderIsMemberProperty() -> String { + return "public var isMemberOf\(typeName): Bool { return knownUIDsOf\(typeName).contains(self) }" + } + + func renderKnownUIDOf() -> [String] { + var result = [String]() + result.append("fileprivate let knownUIDsOf\(typeName): Set = [") + result.append(contentsOf: children.map { "UID.\(typeName).\(propertyName(from: $0)).uid," }.map(indent)) + result.append("]") + return result + } + + var typeName: String { + return name.upperCamelCase + } + + // Private + + private var children: [String] = [] + + private func propertyName(from child: String) -> String { + return type(of: self).escape(removePrefix(from: child).lowerCamelCase) + } + + private func removePrefix(from uidString: String) -> String { + return uidString.replacingOccurrences(of: name + ".", with: "") + } + + private func render(child: String) -> [String] { + let property = propertyName(from: child) + return [ + "/// \(child)", + "public static let \(property): \(name.upperCamelCase) = \"\(child)\"" + ] + } + + private func renderMethods() -> [String] { + return [ + "public static func == (lhs: UID.\(typeName), rhs: UID.\(typeName)) -> Bool { return lhs.uid == rhs.uid }", + "public static func != (lhs: UID.\(typeName), rhs: UID.\(typeName)) -> Bool { return lhs.uid != rhs.uid }", + "public static func == (lhs: UID, rhs: UID.\(typeName)) -> Bool { return lhs == rhs.uid }", + "public static func != (lhs: UID, rhs: UID.\(typeName)) -> Bool { return lhs != rhs.uid }", + "public static func == (lhs: UID.\(typeName), rhs: UID) -> Bool { return lhs.uid == rhs }", + "public static func != (lhs: UID.\(typeName), rhs: UID) -> Bool { return lhs.uid != rhs }", + "public static func == (lhs: UID?, rhs: UID.\(typeName)) -> Bool { return lhs.map { $0 == rhs.uid } ?? false }", + "public static func != (lhs: UID?, rhs: UID.\(typeName)) -> Bool { return lhs.map { $0 != rhs.uid } ?? true }", + "public static func == (lhs: UID.\(typeName), rhs: UID?) -> Bool { return rhs.map { lhs.uid == $0 } ?? false }", + "public static func != (lhs: UID.\(typeName), rhs: UID?) -> Bool { return rhs.map { lhs.uid != $0 } ?? true }", + // FIXME: Remove following when https://bugs.swift.org/browse/SR-3173 will be resolved. + "public init(stringLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) }", + "public init(unicodeScalarLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) }", + "public init(extendedGraphemeClusterLiteral value: String) { self.init(uid: type(of: self)._inferUID(from: value)) }" + ] + } + + // escaping keywords with "`" + private static func escape(_ name: String) -> String { + return keywords.contains(name) ? "`\(name)`" : name + } +} + +extension String { + fileprivate var lowerCamelCase: String { + let comp = components(separatedBy: ".") + return comp.first! + comp.dropFirst().map { $0.capitalized }.joined() + } + + fileprivate var upperCamelCase: String { + return components(separatedBy: ".").map { $0.capitalized }.joined() + } +} diff --git a/sourcekitten.xcodeproj/project.pbxproj b/sourcekitten.xcodeproj/project.pbxproj index b6bbbe009..3b91b0f6f 100644 --- a/sourcekitten.xcodeproj/project.pbxproj +++ b/sourcekitten.xcodeproj/project.pbxproj @@ -13,11 +13,19 @@ 3DEF4C591DBF9C2D00B3B54A /* DocInfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DEF4C581DBF9C2D00B3B54A /* DocInfoTests.swift */; }; 3F0CBB411BAAFF160015BBA8 /* Clang+SourceKitten.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F0CBB401BAAFF160015BBA8 /* Clang+SourceKitten.swift */; }; 3F56EAD01BAB251C006433D0 /* JSONOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F56EACF1BAB251C006433D0 /* JSONOutput.swift */; }; + 6C0328051DBB5F7C001CD693 /* UIDNamespaceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C0328041DBB5F7C001CD693 /* UIDNamespaceTests.swift */; }; + 6C03280C1DBBA966001CD693 /* UIDNamespace.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C03280B1DBBA966001CD693 /* UIDNamespace.swift */; }; + 6C0328111DBBB6A8001CD693 /* UIDNamespace+generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C0328061DBB8D11001CD693 /* UIDNamespace+generated.swift */; }; + 6C2DDBE71DB9BC6100A21181 /* UID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C2DDBE61DB9BC6100A21181 /* UID.swift */; }; 6C4CF5761C78B47F008532C5 /* library_wrapper_sourcekitd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4CF5721C78B47F008532C5 /* library_wrapper_sourcekitd.swift */; }; 6C4CF5771C78B47F008532C5 /* library_wrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4CF5741C78B47F008532C5 /* library_wrapper.swift */; }; 6C4CF6521C798082008532C5 /* library_wrapper_CXString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4CF6481C79802A008532C5 /* library_wrapper_CXString.swift */; }; 6C4CF6551C798086008532C5 /* library_wrapper_Documentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4CF6491C79802A008532C5 /* library_wrapper_Documentation.swift */; }; 6C4CF6581C79808C008532C5 /* library_wrapper_Index.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4CF6471C79802A008532C5 /* library_wrapper_Index.swift */; }; + 6C5100751DEDA9DD00BCB165 /* SourceKitObjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C5100741DEDA9DD00BCB165 /* SourceKitObjectTests.swift */; }; + 6C8DB7701DEBBA05000F59F4 /* SourceKitVariantTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C8DB76F1DEBBA05000F59F4 /* SourceKitVariantTests.swift */; }; + 6C9B587C1DED912400ECBAD4 /* SourceKitObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C9B587B1DED912400ECBAD4 /* SourceKitObject.swift */; }; + 6C9E7D501DB4FB32000F4DE8 /* SourceKitVariant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C9E7D4F1DB4FB32000F4DE8 /* SourceKitVariant.swift */; }; 6CCFCE891CFECFED003239EB /* SWXMLHash.framework in Embed Frameworks into SourceKittenFramework.framework */ = {isa = PBXBuildFile; fileRef = E8C0DFCC1AD349DB007EE3D4 /* SWXMLHash.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 6CCFCE8C1CFECFF1003239EB /* Yams.framework in Embed Frameworks into SourceKittenFramework.framework */ = {isa = PBXBuildFile; fileRef = E80678041CF2749300AFC816 /* Yams.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 6CCFCE8E1CFED000003239EB /* Commandant.framework in Embed Frameworks into SourceKittenFramework.framework */ = {isa = PBXBuildFile; fileRef = E8EBAA5D1A5D374B002F1B8E /* Commandant.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -135,11 +143,19 @@ 3F56EACF1BAB251C006433D0 /* JSONOutput.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONOutput.swift; sourceTree = ""; }; 5499CA961A2394B700783309 /* Components.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Components.plist; sourceTree = ""; }; 5499CA971A2394B700783309 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6C0328041DBB5F7C001CD693 /* UIDNamespaceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIDNamespaceTests.swift; sourceTree = ""; }; + 6C0328061DBB8D11001CD693 /* UIDNamespace+generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIDNamespace+generated.swift"; sourceTree = ""; }; + 6C03280B1DBBA966001CD693 /* UIDNamespace.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIDNamespace.swift; sourceTree = ""; }; + 6C2DDBE61DB9BC6100A21181 /* UID.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UID.swift; sourceTree = ""; }; 6C4CF5721C78B47F008532C5 /* library_wrapper_sourcekitd.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = library_wrapper_sourcekitd.swift; sourceTree = ""; }; 6C4CF5741C78B47F008532C5 /* library_wrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = library_wrapper.swift; sourceTree = ""; }; 6C4CF6471C79802A008532C5 /* library_wrapper_Index.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = library_wrapper_Index.swift; sourceTree = ""; }; 6C4CF6481C79802A008532C5 /* library_wrapper_CXString.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = library_wrapper_CXString.swift; sourceTree = ""; }; 6C4CF6491C79802A008532C5 /* library_wrapper_Documentation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = library_wrapper_Documentation.swift; sourceTree = ""; }; + 6C5100741DEDA9DD00BCB165 /* SourceKitObjectTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SourceKitObjectTests.swift; sourceTree = ""; }; + 6C8DB76F1DEBBA05000F59F4 /* SourceKitVariantTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SourceKitVariantTests.swift; sourceTree = ""; }; + 6C9B587B1DED912400ECBAD4 /* SourceKitObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SourceKitObject.swift; sourceTree = ""; }; + 6C9E7D4F1DB4FB32000F4DE8 /* SourceKitVariant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SourceKitVariant.swift; sourceTree = ""; }; 6CFC18F01C7F2FB900CD70E1 /* module.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; B2FA804AA9D4427FF571EFB2 /* SwiftLangSyntax.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftLangSyntax.swift; sourceTree = ""; }; C236E84A1DFF5120003807D2 /* YamlRequestCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YamlRequestCommand.swift; sourceTree = ""; }; @@ -403,6 +419,8 @@ E86847391A587B4D0043DC65 /* Request.swift */, E8A9B8911B56D1B100CD17D4 /* SourceDeclaration.swift */, D0D1217119E87B05005E4BAA /* SourceKittenFramework.h */, + 6C9B587B1DED912400ECBAD4 /* SourceKitObject.swift */, + 6C9E7D4F1DB4FB32000F4DE8 /* SourceKitVariant.swift */, E806D28C1BE0589B00D1BE41 /* SourceLocation.swift */, E8AE53C61A5B5FCA0092D24A /* String+SourceKitten.swift */, E834740E1A593B5B00532B9A /* Structure.swift */, @@ -414,6 +432,9 @@ E8CC8A2C1A587FD300D1FEC7 /* SyntaxMap.swift */, E80F236A1A5CB04100FD2352 /* SyntaxToken.swift */, E806D28E1BE058B100D1BE41 /* Text.swift */, + 6C2DDBE61DB9BC6100A21181 /* UID.swift */, + 6C03280B1DBBA966001CD693 /* UIDNamespace.swift */, + 6C0328061DBB8D11001CD693 /* UIDNamespace+generated.swift */, E8A9B88F1B56CB5500CD17D4 /* Xcode.swift */, B2FA804AA9D4427FF571EFB2 /* SwiftLangSyntax.swift */, ); @@ -445,10 +466,13 @@ E8241CA21A5E01840047687E /* ModuleTests.swift */, E8C9EA091A5C9A2900A6D4D1 /* OffsetMapTests.swift */, E805A0471B55CBAF00EA654A /* SourceKitTests.swift */, + 6C5100741DEDA9DD00BCB165 /* SourceKitObjectTests.swift */, + 6C8DB76F1DEBBA05000F59F4 /* SourceKitVariantTests.swift */, E8C9EA071A5C99C400A6D4D1 /* StringTests.swift */, E8C9EA031A5C986A00A6D4D1 /* StructureTests.swift */, E80F23661A5CADD900FD2352 /* SwiftDocsTests.swift */, D0DB09A319EA354200234B16 /* SyntaxTests.swift */, + 6C0328041DBB5F7C001CD693 /* UIDNamespaceTests.swift */, ); name = SourceKittenFrameworkTests; path = Tests/SourceKittenFrameworkTests; @@ -653,6 +677,7 @@ buildActionMask = 2147483647; files = ( E82882541DAEEDD1002E0564 /* LinuxCompatibility.swift in Sources */, + 6C9E7D501DB4FB32000F4DE8 /* SourceKitVariant.swift in Sources */, E806D2931BE058D600D1BE41 /* Documentation.swift in Sources */, 3F0CBB411BAAFF160015BBA8 /* Clang+SourceKitten.swift in Sources */, 2E8FF7101C6268C100F280F0 /* StatementKind.swift in Sources */, @@ -660,17 +685,21 @@ E8D4743B1A648F290011A49C /* ClangTranslationUnit.swift in Sources */, E8EE34BF1B9A502F00947605 /* CodeCompletionItem.swift in Sources */, E852418F1A5F4FB3007099FB /* Dictionary+Merge.swift in Sources */, + 6C03280C1DBBA966001CD693 /* UIDNamespace.swift in Sources */, + 6C9B587C1DED912400ECBAD4 /* SourceKitObject.swift in Sources */, E847636A1A5A0651000EAE22 /* File.swift in Sources */, 6C4CF5771C78B47F008532C5 /* library_wrapper.swift in Sources */, 3F56EAD01BAB251C006433D0 /* JSONOutput.swift in Sources */, E8A18A3B1A58971D000362B7 /* Language.swift in Sources */, E806D28F1BE058B100D1BE41 /* Text.swift in Sources */, E8241CA51A5E01A10047687E /* Module.swift in Sources */, + 6C0328111DBBB6A8001CD693 /* UIDNamespace+generated.swift in Sources */, E877D9271B5693E70095BB2B /* ObjCDeclarationKind.swift in Sources */, 6C4CF6521C798082008532C5 /* library_wrapper_CXString.swift in Sources */, E83748C31A5BCD7900862B1B /* OffsetMap.swift in Sources */, E806D2911BE058C400D1BE41 /* Parameter.swift in Sources */, E868473A1A587B4D0043DC65 /* Request.swift in Sources */, + 6C2DDBE71DB9BC6100A21181 /* UID.swift in Sources */, E8A9B8921B56D1B100CD17D4 /* SourceDeclaration.swift in Sources */, E806D28D1BE0589B00D1BE41 /* SourceLocation.swift in Sources */, E8AE53C71A5B5FCA0092D24A /* String+SourceKitten.swift in Sources */, @@ -695,12 +724,15 @@ E8AB1A301A64A21400452012 /* ClangTranslationUnitTests.swift in Sources */, E845EFEC1B9941AA00CFA57B /* CodeCompletionTests.swift in Sources */, E805A04A1B560FCA00EA654A /* FileTests.swift in Sources */, + 6C0328051DBB5F7C001CD693 /* UIDNamespaceTests.swift in Sources */, E8241CA31A5E01840047687E /* ModuleTests.swift in Sources */, 3DEF4C591DBF9C2D00B3B54A /* DocInfoTests.swift in Sources */, + 6C5100751DEDA9DD00BCB165 /* SourceKitObjectTests.swift in Sources */, E8C9EA0A1A5C9A2900A6D4D1 /* OffsetMapTests.swift in Sources */, E805A0481B55CBAF00EA654A /* SourceKitTests.swift in Sources */, E8C9EA081A5C99C400A6D4D1 /* StringTests.swift in Sources */, E8C9EA041A5C986A00A6D4D1 /* StructureTests.swift in Sources */, + 6C8DB7701DEBBA05000F59F4 /* SourceKitVariantTests.swift in Sources */, E80F23671A5CADD900FD2352 /* SwiftDocsTests.swift in Sources */, D0DB09A419EA354200234B16 /* SyntaxTests.swift in Sources */, ); @@ -801,6 +833,7 @@ CURRENT_PROJECT_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; + ENABLE_TESTABILITY = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; FRAMEWORK_VERSION = A; INFOPLIST_FILE = Source/SourceKittenFramework/Info.plist;