From 43fa288ea05dc0f0cf946b94158874b2cde240f8 Mon Sep 17 00:00:00 2001 From: Colton Schlosser Date: Mon, 22 Jul 2019 00:56:12 -0400 Subject: [PATCH] Move CursorInfo referenced USR code from swiftlint (#605) From https://github.com/realm/SwiftLint/pull/2818 --- CHANGELOG.md | 5 ++ .../CursorInfo+Parsing.swift | 31 +++++++++++ Tests/LinuxMain.swift | 1 + .../CursorInfoParsingTests.swift | 53 +++++++++++++++++++ sourcekitten.xcodeproj/project.pbxproj | 8 +++ 5 files changed, 98 insertions(+) create mode 100644 Source/SourceKittenFramework/CursorInfo+Parsing.swift create mode 100644 Tests/SourceKittenFrameworkTests/CursorInfoParsingTests.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b3041650..1ead3e1f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,11 @@ * Add `cursorInfoUSR` case to the `Request`. [Timofey Solonin](https://github.com/biboran) +* Add a `Dictionary.referencedUSRs` + computed property to retrieve referenced USRs from a SourceKit cursor info + response. + [Colton Schlosser](https://github.com/cltnschlosser) + ##### Bug Fixes * Fix `testCommandantDocsSPM` failed on using Swift Package in Xcode 11, because diff --git a/Source/SourceKittenFramework/CursorInfo+Parsing.swift b/Source/SourceKittenFramework/CursorInfo+Parsing.swift new file mode 100644 index 000000000..85c131c03 --- /dev/null +++ b/Source/SourceKittenFramework/CursorInfo+Parsing.swift @@ -0,0 +1,31 @@ +// +// CursorInfo+USR.swift +// SourceKittenFramework +// +// Created by Colton Schlosser on 7/21/19. +// Copyright © 2019 SourceKitten. All rights reserved. +// + +import SWXMLHash + +public extension Dictionary where Key == String, Value == SourceKitRepresentable { + var referencedUSRs: [String] { + if let usr = self["key.usr"] as? String, + let kind = self["key.kind"] as? String, + kind.contains("source.lang.swift.ref") { + if let relatedDecls = self["key.related_decls"] as? [[String: SourceKitRepresentable]] { + return [usr] + relatedDecls.compactMap { ($0["key.annotated_decl"] as? String)?.relatedNameUSR } + } else { + return [usr] + } + } + + return [] + } +} + +private extension String { + var relatedNameUSR: String? { + return SWXMLHash.parse(self)["RelatedName"].element?.value(ofAttribute: "usr") + } +} diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index c73148ff1..56f7c158b 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -4,6 +4,7 @@ import XCTest XCTMain([ // testCase(ClangTranslationUnitTests.allTests), testCase(CodeCompletionTests.allTests), + testCase(CursorInfoParsingTests.allTests), testCase(DocInfoTests.allTests), testCase(FileTests.allTests), testCase(ModuleTests.allTests), diff --git a/Tests/SourceKittenFrameworkTests/CursorInfoParsingTests.swift b/Tests/SourceKittenFrameworkTests/CursorInfoParsingTests.swift new file mode 100644 index 000000000..d4d1b0723 --- /dev/null +++ b/Tests/SourceKittenFrameworkTests/CursorInfoParsingTests.swift @@ -0,0 +1,53 @@ +// +// CursorInfoParsingTests.swift +// SourceKittenFramework +// +// Created by Colton Schlosser on 7/21/19. +// Copyright © 2019 SourceKitten. All rights reserved. +// + +import SourceKittenFramework +import XCTest + +final class CursorInfoParsingTests: XCTestCase { + + func testNoReferencedUSR() { + let cursorInfo: [String: SourceKitRepresentable] = [ + "key.usr": "s:4main5limitL_Sivp", + "key.kind": "source.lang.swift.decl.var.local" + ] + + XCTAssertEqual(cursorInfo.referencedUSRs, []) + } + + func testSingleReferencedUSR() { + let cursorInfo: [String: SourceKitRepresentable] = [ + "key.usr": "s:4main5limitL_Sivp", + "key.kind": "source.lang.swift.ref.var.local" + ] + + XCTAssertEqual(cursorInfo.referencedUSRs, ["s:4main5limitL_Sivp"]) + } + + func testRelatedReferencedUSR() { + let cursorInfo: [String: SourceKitRepresentable] = [ + "key.usr": "s:4main5limitL_Sivp", + "key.kind": "source.lang.swift.ref.var.local", + "key.related_decls": [ + ["key.annotated_decl": "limit"] + ] + ] + + XCTAssertEqual(cursorInfo.referencedUSRs, ["s:4main5limitL_Sivp", "s:4main5limit33_BF49849BA67C991867DA082EF03F5F16LLSivp"]) + } +} + +extension CursorInfoParsingTests { + static var allTests: [(String, (CursorInfoParsingTests) -> () throws -> Void)] { + return [ + ("testNoReferencedUSR", testNoReferencedUSR), + ("testSingleReferencedUSR", testSingleReferencedUSR), + ("testRelatedReferencedUSR", testRelatedReferencedUSR) + ] + } +} diff --git a/sourcekitten.xcodeproj/project.pbxproj b/sourcekitten.xcodeproj/project.pbxproj index b7e426385..84252376d 100644 --- a/sourcekitten.xcodeproj/project.pbxproj +++ b/sourcekitten.xcodeproj/project.pbxproj @@ -16,6 +16,8 @@ 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 */; }; + 557592AF22E542CA0028FED4 /* CursorInfo+Parsing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 557592AE22E542CA0028FED4 /* CursorInfo+Parsing.swift */; }; + 557592B322E548BC0028FED4 /* CursorInfoParsingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 557592B022E545280028FED4 /* CursorInfoParsingTests.swift */; }; 55DB6A9722DEABD100666C6A /* UIDRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55DB6A9622DEABD000666C6A /* UIDRepresentable.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 */; }; @@ -148,6 +150,8 @@ 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 = ""; }; + 557592AE22E542CA0028FED4 /* CursorInfo+Parsing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CursorInfo+Parsing.swift"; sourceTree = ""; }; + 557592B022E545280028FED4 /* CursorInfoParsingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CursorInfoParsingTests.swift; sourceTree = ""; }; 55DB6A9622DEABD000666C6A /* UIDRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDRepresentable.swift; sourceTree = ""; }; 6C4981EB1FE33F4500633AC8 /* Mac-XCTest.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Mac-XCTest.xcconfig"; sourceTree = ""; }; 6C4CF5721C78B47F008532C5 /* library_wrapper_sourcekitd.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = library_wrapper_sourcekitd.swift; sourceTree = ""; }; @@ -435,6 +439,7 @@ 3F0CBB401BAAFF160015BBA8 /* Clang+SourceKitten.swift */, E8D4743A1A648F290011A49C /* ClangTranslationUnit.swift */, E8EE34BE1B9A502F00947605 /* CodeCompletionItem.swift */, + 557592AE22E542CA0028FED4 /* CursorInfo+Parsing.swift */, E852418E1A5F4FB3007099FB /* Dictionary+Merge.swift */, E806D2921BE058D600D1BE41 /* Documentation.swift */, E84763691A5A0651000EAE22 /* File.swift */, @@ -496,6 +501,7 @@ E801EA111DB8604100AD28E6 /* LinuxMain.swift */, E8AB1A2F1A64A21400452012 /* ClangTranslationUnitTests.swift */, E845EFEB1B9941AA00CFA57B /* CodeCompletionTests.swift */, + 557592B022E545280028FED4 /* CursorInfoParsingTests.swift */, 3DEF4C581DBF9C2D00B3B54A /* DocInfoTests.swift */, E805A0491B560FCA00EA654A /* FileTests.swift */, E8241CA21A5E01840047687E /* ModuleTests.swift */, @@ -725,6 +731,7 @@ 6C4CF5771C78B47F008532C5 /* library_wrapper.swift in Sources */, 3F56EAD01BAB251C006433D0 /* JSONOutput.swift in Sources */, 8F935B342288C05A00971070 /* File+Hashable.swift in Sources */, + 557592AF22E542CA0028FED4 /* CursorInfo+Parsing.swift in Sources */, E8A18A3B1A58971D000362B7 /* Language.swift in Sources */, E806D28F1BE058B100D1BE41 /* Text.swift in Sources */, 6CC1639C202AA3AF0086C459 /* SourceKitObject.swift in Sources */, @@ -757,6 +764,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 557592B322E548BC0028FED4 /* CursorInfoParsingTests.swift in Sources */, BCF9238E228AD94E0008C684 /* CursorInfoUSRTests.swift in Sources */, E8AB1A301A64A21400452012 /* ClangTranslationUnitTests.swift in Sources */, E845EFEC1B9941AA00CFA57B /* CodeCompletionTests.swift in Sources */,