mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-09-30 23:15:39 +02:00
Consolidate all test that test functionality for copy destinations. Also rename the test case because not only headers may be declared as copied using `copyDestinations`.
707 lines
22 KiB
Swift
707 lines
22 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import BuildServerIntegration
|
|
@_spi(SourceKitLSP) import BuildServerProtocol
|
|
@_spi(SourceKitLSP) import LanguageServerProtocol
|
|
@_spi(Testing) @_spi(SourceKitLSP) import SKLogging
|
|
import SKTestSupport
|
|
import SwiftExtensions
|
|
import XCTest
|
|
|
|
class DefinitionTests: SourceKitLSPTestCase {
|
|
func testJumpToDefinitionAtEndOfIdentifier() async throws {
|
|
let testClient = try await TestSourceKitLSPClient()
|
|
let uri = DocumentURI(for: .swift)
|
|
|
|
let positions = testClient.openDocument(
|
|
"""
|
|
let 1️⃣foo = 1
|
|
_ = foo2️⃣
|
|
""",
|
|
uri: uri
|
|
)
|
|
|
|
let response = try await testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["2️⃣"])
|
|
)
|
|
XCTAssertEqual(response?.locations, [Location(uri: uri, range: Range(positions["1️⃣"]))])
|
|
}
|
|
|
|
func testJumpToDefinitionIncludesOverrides() async throws {
|
|
let project = try await IndexedSingleSwiftFileTestProject(
|
|
"""
|
|
protocol TestProtocol {
|
|
func 1️⃣doThing()
|
|
}
|
|
|
|
struct TestImpl: TestProtocol {
|
|
func 2️⃣doThing() { }
|
|
}
|
|
|
|
func anyTestProtocol(value: any TestProtocol) {
|
|
value.3️⃣doThing()
|
|
}
|
|
"""
|
|
)
|
|
|
|
let response = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(project.fileURI), position: project.positions["3️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
response?.locations,
|
|
[
|
|
Location(uri: project.fileURI, range: Range(project.positions["1️⃣"])),
|
|
Location(uri: project.fileURI, range: Range(project.positions["2️⃣"])),
|
|
]
|
|
)
|
|
}
|
|
|
|
func testJumpToDefinitionFiltersByReceiver() async throws {
|
|
let project = try await IndexedSingleSwiftFileTestProject(
|
|
"""
|
|
class A {
|
|
func 1️⃣doThing() {}
|
|
}
|
|
class B: A {}
|
|
class C: B {
|
|
override func 2️⃣doThing() {}
|
|
}
|
|
class D: A {
|
|
override func doThing() {}
|
|
}
|
|
|
|
func test(value: B) {
|
|
value.3️⃣doThing()
|
|
}
|
|
"""
|
|
)
|
|
|
|
let response = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(project.fileURI), position: project.positions["3️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
response?.locations,
|
|
[
|
|
Location(uri: project.fileURI, range: Range(project.positions["1️⃣"])),
|
|
Location(uri: project.fileURI, range: Range(project.positions["2️⃣"])),
|
|
]
|
|
)
|
|
}
|
|
|
|
func testDynamicJumpToDefinitionInClang() async throws {
|
|
let project = try await SwiftPMTestProject(
|
|
files: [
|
|
"Sources/MyLibrary/include/dummy.h": "",
|
|
"test.cpp": """
|
|
struct Base {
|
|
virtual void 1️⃣doStuff() {}
|
|
};
|
|
|
|
struct Sub: Base {
|
|
void 2️⃣doStuff() override {}
|
|
};
|
|
|
|
void test(Base base) {
|
|
base.3️⃣doStuff();
|
|
}
|
|
""",
|
|
],
|
|
enableBackgroundIndexing: true
|
|
)
|
|
let (uri, positions) = try project.openDocument("test.cpp")
|
|
|
|
let response = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["3️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
response?.locations,
|
|
[
|
|
Location(uri: uri, range: Range(positions["1️⃣"])),
|
|
Location(uri: uri, range: Range(positions["2️⃣"])),
|
|
]
|
|
)
|
|
}
|
|
|
|
func testJumpToCDefinitionFromSwift() async throws {
|
|
let project = try await SwiftPMTestProject(
|
|
files: [
|
|
"Sources/MyLibrary/include/test.h": """
|
|
void myFunc(void);
|
|
""",
|
|
"Sources/MyLibrary/test.c": """
|
|
#include "test.h"
|
|
|
|
void 1️⃣myFunc(void) {}
|
|
""",
|
|
"Sources/MySwiftLibrary/main.swift":
|
|
"""
|
|
import MyLibrary
|
|
|
|
2️⃣myFunc()
|
|
""",
|
|
],
|
|
manifest: """
|
|
let package = Package(
|
|
name: "MyLibrary",
|
|
targets: [
|
|
.target(name: "MyLibrary"),
|
|
.target(name: "MySwiftLibrary", dependencies: ["MyLibrary"])
|
|
]
|
|
)
|
|
""",
|
|
enableBackgroundIndexing: true
|
|
)
|
|
|
|
let (uri, positions) = try project.openDocument("main.swift")
|
|
|
|
let response = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["2️⃣"])
|
|
)
|
|
|
|
let location = try XCTUnwrap(response?.locations?.only)
|
|
XCTAssertEqual(
|
|
location,
|
|
Location(uri: try project.uri(for: "test.c"), range: Range(try project.position(of: "1️⃣", in: "test.c")))
|
|
)
|
|
}
|
|
|
|
func testReportInitializerOnDefinitionForType() async throws {
|
|
let testClient = try await TestSourceKitLSPClient()
|
|
let uri = DocumentURI(for: .swift)
|
|
let positions = testClient.openDocument(
|
|
"""
|
|
struct 1️⃣Foo {
|
|
2️⃣init() {}
|
|
}
|
|
_ = 3️⃣Foo()
|
|
""",
|
|
uri: uri
|
|
)
|
|
|
|
let response = try await testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["3️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
response,
|
|
.locations([
|
|
Location(uri: uri, range: Range(positions["1️⃣"])),
|
|
Location(uri: uri, range: Range(positions["2️⃣"])),
|
|
])
|
|
)
|
|
}
|
|
|
|
func testAmbiguousDefinition() async throws {
|
|
let testClient = try await TestSourceKitLSPClient()
|
|
let uri = DocumentURI(for: .swift)
|
|
let positions = testClient.openDocument(
|
|
"""
|
|
func 1️⃣foo() -> Int { 1 }
|
|
func 2️⃣foo() -> String { "" }
|
|
func test() {
|
|
_ = 3️⃣foo()
|
|
}
|
|
""",
|
|
uri: uri
|
|
)
|
|
|
|
let response = try await testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["3️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
response,
|
|
.locations([
|
|
Location(uri: uri, range: Range(positions["1️⃣"])),
|
|
Location(uri: uri, range: Range(positions["2️⃣"])),
|
|
])
|
|
)
|
|
}
|
|
|
|
func testDefinitionOfClassBetweenModulesObjC() async throws {
|
|
try SkipUnless.platformIsDarwin("@import in Objective-C is not enabled on non-Darwin")
|
|
let project = try await SwiftPMTestProject(
|
|
files: [
|
|
"LibA/include/LibA.h": """
|
|
@interface 1️⃣LibAClass2️⃣
|
|
- (void)doSomething;
|
|
@end
|
|
""",
|
|
"LibB/include/dummy.h": "",
|
|
"LibB/LibB.m": """
|
|
@import LibA;
|
|
@interface Test
|
|
@end
|
|
|
|
@implementation Test
|
|
- (void)test:(3️⃣LibAClass *)libAClass {
|
|
[libAClass doSomething];
|
|
}
|
|
@end
|
|
""",
|
|
],
|
|
manifest: """
|
|
let package = Package(
|
|
name: "MyLibrary",
|
|
targets: [
|
|
.target(name: "LibA"),
|
|
.target(name: "LibB", dependencies: ["LibA"]),
|
|
]
|
|
)
|
|
"""
|
|
)
|
|
let (uri, positions) = try project.openDocument("LibB.m")
|
|
let response = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["3️⃣"])
|
|
)
|
|
|
|
let location = try XCTUnwrap(response?.locations?.only)
|
|
XCTAssertEqual(location, try project.location(from: "1️⃣", to: "2️⃣", in: "LibA.h"))
|
|
}
|
|
|
|
func testDefinitionOfMethodBetweenModulesObjC() async throws {
|
|
try SkipUnless.platformIsDarwin("@import in Objective-C is not enabled on non-Darwin")
|
|
let project = try await SwiftPMTestProject(
|
|
files: [
|
|
"LibA/include/LibA.h": """
|
|
@interface LibAClass
|
|
- (void)1️⃣doSomething2️⃣;
|
|
@end
|
|
""",
|
|
"LibB/include/dummy.h": "",
|
|
"LibB/LibB.m": """
|
|
@import LibA;
|
|
@interface Test
|
|
@end
|
|
|
|
@implementation Test
|
|
- (void)test:(LibAClass *)libAClass {
|
|
[libAClass 3️⃣doSomething];
|
|
}
|
|
@end
|
|
""",
|
|
],
|
|
manifest: """
|
|
let package = Package(
|
|
name: "MyLibrary",
|
|
targets: [
|
|
.target(name: "LibA"),
|
|
.target(name: "LibB", dependencies: ["LibA"]),
|
|
]
|
|
)
|
|
"""
|
|
)
|
|
let (uri, positions) = try project.openDocument("LibB.m")
|
|
let response = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["3️⃣"])
|
|
)
|
|
|
|
let location = try XCTUnwrap(response?.locations?.only)
|
|
XCTAssertEqual(location, try project.location(from: "1️⃣", to: "2️⃣", in: "LibA.h"))
|
|
}
|
|
|
|
func testDefinitionOfImplicitInitializer() async throws {
|
|
let testClient = try await TestSourceKitLSPClient()
|
|
let uri = DocumentURI(for: .swift)
|
|
|
|
let positions = testClient.openDocument(
|
|
"""
|
|
class 1️⃣Foo {}
|
|
|
|
func test() {
|
|
2️⃣Foo()
|
|
}
|
|
""",
|
|
uri: uri
|
|
)
|
|
|
|
let response = try await testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["2️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
response?.locations,
|
|
[Location(uri: uri, range: Range(positions["1️⃣"]))]
|
|
)
|
|
}
|
|
|
|
func testFileDependencyUpdatedWithinSameModule() async throws {
|
|
try SkipUnless.longTestsEnabled()
|
|
|
|
let project = try await SwiftPMTestProject(
|
|
files: [
|
|
"FileA.swift": "",
|
|
"FileB.swift": """
|
|
func test() {
|
|
1️⃣sayHello()
|
|
}
|
|
""",
|
|
],
|
|
capabilities: ClientCapabilities(
|
|
workspace: WorkspaceClientCapabilities(diagnostics: RefreshRegistrationCapability(refreshSupport: true))
|
|
),
|
|
enableBackgroundIndexing: true
|
|
)
|
|
|
|
let (bUri, bPositions) = try project.openDocument("FileB.swift")
|
|
let beforeChangingFileA = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(bUri), position: bPositions["1️⃣"])
|
|
)
|
|
XCTAssertNil(beforeChangingFileA)
|
|
|
|
let (aUri, updatedAPositions) = try await project.changeFileOnDisk(
|
|
"FileA.swift",
|
|
newMarkedContents: "func 2️⃣sayHello() {}"
|
|
)
|
|
|
|
// Wait until SourceKit-LSP has handled the `DidChangeWatchedFilesNotification` (which it only does after a delay
|
|
// because it debounces these notifications), indicated by it telling us that we should refresh diagnostics.
|
|
let diagnosticRefreshRequestReceived = self.expectation(description: "DiagnosticsRefreshRequest received")
|
|
project.testClient.handleSingleRequest { (request: DiagnosticsRefreshRequest) in
|
|
diagnosticRefreshRequestReceived.fulfill()
|
|
return VoidResponse()
|
|
}
|
|
try await fulfillmentOfOrThrow(diagnosticRefreshRequestReceived)
|
|
|
|
let afterChangingFileA = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(bUri), position: bPositions["1️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
afterChangingFileA,
|
|
.locations([Location(uri: aUri, range: Range(updatedAPositions["2️⃣"]))])
|
|
)
|
|
|
|
let afterChange = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(bUri), position: bPositions["1️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
afterChange,
|
|
.locations([Location(uri: aUri, range: Range(updatedAPositions["2️⃣"]))])
|
|
)
|
|
}
|
|
|
|
func testDependentModuleGotBuilt() async throws {
|
|
try SkipUnless.longTestsEnabled()
|
|
let project = try await SwiftPMTestProject(
|
|
files: [
|
|
"LibA/LibA.swift": """
|
|
public func 1️⃣sayHello() {}
|
|
""",
|
|
"LibB/LibB.swift": """
|
|
import LibA
|
|
|
|
func test() {
|
|
2️⃣sayHello()
|
|
}
|
|
""",
|
|
],
|
|
manifest: """
|
|
let package = Package(
|
|
name: "MyLibrary",
|
|
targets: [
|
|
.target(name: "LibA"),
|
|
.target(name: "LibB", dependencies: ["LibA"]),
|
|
]
|
|
)
|
|
""",
|
|
capabilities: ClientCapabilities(
|
|
workspace: WorkspaceClientCapabilities(diagnostics: RefreshRegistrationCapability(refreshSupport: true))
|
|
)
|
|
)
|
|
|
|
let (bUri, bPositions) = try project.openDocument("LibB.swift")
|
|
let beforeBuilding = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(bUri), position: bPositions["2️⃣"])
|
|
)
|
|
XCTAssertNil(beforeBuilding)
|
|
|
|
try await SwiftPMTestProject.build(at: project.scratchDirectory)
|
|
|
|
project.testClient.send(
|
|
DidChangeWatchedFilesNotification(
|
|
changes:
|
|
FileManager.default.findFiles(withExtension: "swiftmodule", in: project.scratchDirectory).map {
|
|
FileEvent(uri: DocumentURI($0), type: .created)
|
|
}
|
|
)
|
|
)
|
|
|
|
// Wait until SourceKit-LSP has handled the `DidChangeWatchedFilesNotification` (which it only does after a delay
|
|
// because it debounces these notifications), indicated by it telling us that we should refresh diagnostics.
|
|
let diagnosticRefreshRequestReceived = self.expectation(description: "DiagnosticsRefreshRequest received")
|
|
project.testClient.handleSingleRequest { (request: DiagnosticsRefreshRequest) in
|
|
diagnosticRefreshRequestReceived.fulfill()
|
|
return VoidResponse()
|
|
}
|
|
try await fulfillmentOfOrThrow(diagnosticRefreshRequestReceived)
|
|
|
|
let afterBuilding = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(bUri), position: bPositions["2️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
afterBuilding,
|
|
.locations([try project.location(from: "1️⃣", to: "1️⃣", in: "LibA.swift")])
|
|
)
|
|
}
|
|
|
|
func testIndexBasedDefinitionAfterFileMove() async throws {
|
|
let project = try await SwiftPMTestProject(
|
|
files: [
|
|
"definition.swift": """
|
|
class MyClass {
|
|
func 1️⃣foo() {}
|
|
}
|
|
""",
|
|
"caller.swift": """
|
|
func test(myClass: MyClass) {
|
|
myClass.2️⃣foo()
|
|
}
|
|
""",
|
|
],
|
|
enableBackgroundIndexing: true
|
|
)
|
|
|
|
let definitionUri = try project.uri(for: "definition.swift")
|
|
let (callerUri, callerPositions) = try project.openDocument("caller.swift")
|
|
|
|
// Validate that we get correct rename results before moving the definition file.
|
|
let resultBeforeFileMove = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(callerUri), position: callerPositions["2️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
resultBeforeFileMove,
|
|
.locations([
|
|
Location(uri: definitionUri, range: Range(try project.position(of: "1️⃣", in: "definition.swift")))
|
|
])
|
|
)
|
|
|
|
let movedDefinitionUri =
|
|
DocumentURI(
|
|
definitionUri.fileURL!
|
|
.deletingLastPathComponent()
|
|
.appending(component: "movedDefinition.swift")
|
|
)
|
|
|
|
try FileManager.default.moveItem(at: XCTUnwrap(definitionUri.fileURL), to: XCTUnwrap(movedDefinitionUri.fileURL))
|
|
|
|
project.testClient.send(
|
|
DidChangeWatchedFilesNotification(changes: [
|
|
FileEvent(uri: definitionUri, type: .deleted), FileEvent(uri: movedDefinitionUri, type: .created),
|
|
])
|
|
)
|
|
|
|
// Ensure that the DidChangeWatchedFilesNotification is handled before we continue.
|
|
try await project.testClient.send(SynchronizeRequest(index: true))
|
|
|
|
let resultAfterFileMove = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(callerUri), position: callerPositions["2️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
resultAfterFileMove,
|
|
.locations([
|
|
Location(uri: movedDefinitionUri, range: Range(try project.position(of: "1️⃣", in: "definition.swift")))
|
|
])
|
|
)
|
|
}
|
|
|
|
func testJumpToDefinitionOnProtocolImplementationJumpsToRequirement() async throws {
|
|
let project = try await IndexedSingleSwiftFileTestProject(
|
|
"""
|
|
protocol TestProtocol {
|
|
func 1️⃣doThing()
|
|
}
|
|
|
|
struct TestImpl: TestProtocol {
|
|
func 2️⃣do3️⃣Thing() { }
|
|
}
|
|
"""
|
|
)
|
|
|
|
let definitionFromBaseName = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(project.fileURI), position: project.positions["2️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
definitionFromBaseName,
|
|
.locations([Location(uri: project.fileURI, range: Range(project.positions["1️⃣"]))])
|
|
)
|
|
|
|
let definitionFromInsideBaseName = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(project.fileURI), position: project.positions["3️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
definitionFromInsideBaseName,
|
|
.locations([Location(uri: project.fileURI, range: Range(project.positions["1️⃣"]))])
|
|
)
|
|
}
|
|
|
|
func testJumpToDefinitionOnProtocolImplementationShowsAllFulfilledRequirements() async throws {
|
|
let project = try await IndexedSingleSwiftFileTestProject(
|
|
"""
|
|
protocol TestProtocol {
|
|
func 1️⃣doThing()
|
|
}
|
|
|
|
protocol OtherProtocol {
|
|
func 2️⃣doThing()
|
|
}
|
|
|
|
struct TestImpl: TestProtocol, OtherProtocol {
|
|
func 3️⃣doThing() { }
|
|
}
|
|
"""
|
|
)
|
|
|
|
let result = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(project.fileURI), position: project.positions["3️⃣"])
|
|
)
|
|
XCTAssertEqual(
|
|
result,
|
|
.locations([
|
|
Location(uri: project.fileURI, range: Range(project.positions["1️⃣"])),
|
|
Location(uri: project.fileURI, range: Range(project.positions["2️⃣"])),
|
|
])
|
|
)
|
|
}
|
|
|
|
func testJumpToSatisfiedProtocolRequirementInExtension() async throws {
|
|
let project = try await IndexedSingleSwiftFileTestProject(
|
|
"""
|
|
protocol TestProtocol {
|
|
func 1️⃣doThing()
|
|
}
|
|
|
|
struct TestImpl: TestProtocol {}
|
|
extension TestImpl {
|
|
func 2️⃣doThing() { }
|
|
}
|
|
"""
|
|
)
|
|
|
|
let response = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(project.fileURI), position: project.positions["1️⃣"])
|
|
)
|
|
XCTAssertEqual(response?.locations, [Location(uri: project.fileURI, range: Range(project.positions["2️⃣"]))])
|
|
}
|
|
|
|
func testJumpToSwiftInterfaceIfIndexLookupFails() async throws {
|
|
let project = try await SwiftPMTestProject(
|
|
files: [
|
|
"Lib/Lib.swift": """
|
|
public func abc() {}
|
|
""",
|
|
"Executable/Executable.swift": """
|
|
import Lib
|
|
|
|
func test() {
|
|
1️⃣abc()
|
|
}
|
|
""",
|
|
],
|
|
manifest: """
|
|
let package = Package(
|
|
name: "MyLibrary",
|
|
targets: [
|
|
.target(name: "Lib"),
|
|
.executableTarget(name: "Executable", dependencies: ["Lib"])
|
|
]
|
|
)
|
|
"""
|
|
)
|
|
try await SwiftPMTestProject.build(
|
|
at: project.scratchDirectory,
|
|
extraArguments: ["--disable-index-store", "-Xswiftc", "-avoid-emit-module-source-info"]
|
|
)
|
|
|
|
let (uri, positions) = try project.openDocument("Executable.swift")
|
|
let definitions = try await project.testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["1️⃣"])
|
|
)
|
|
XCTAssertTrue(definitions?.locations?.first?.uri.pseudoPath.hasSuffix("Lib.swiftinterface") ?? false)
|
|
}
|
|
|
|
func testDefinitionOnLiteralsShouldReturnEmpty() async throws {
|
|
let testClient = try await TestSourceKitLSPClient()
|
|
let uri = DocumentURI(for: .swift)
|
|
|
|
let positions = testClient.openDocument(
|
|
"""
|
|
let message = "1️⃣Hello"
|
|
let count = 2️⃣25
|
|
let flag = 3️⃣true
|
|
let pi = 4️⃣3.14
|
|
let nothing: Int? = 5️⃣nil
|
|
""",
|
|
uri: uri
|
|
)
|
|
|
|
// Test string literal
|
|
let stringResponse = try await testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["1️⃣"])
|
|
)
|
|
XCTAssertNil(stringResponse, "Jump-to-definition should not work on string literals")
|
|
|
|
// Test integer literal
|
|
let intResponse = try await testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["2️⃣"])
|
|
)
|
|
XCTAssertNil(intResponse, "Jump-to-definition should not work on integer literals")
|
|
|
|
// Test boolean literal
|
|
let boolResponse = try await testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["3️⃣"])
|
|
)
|
|
XCTAssertNil(boolResponse, "Jump-to-definition should not work on boolean literals")
|
|
|
|
// Test float literal
|
|
let floatResponse = try await testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["4️⃣"])
|
|
)
|
|
XCTAssertNil(floatResponse, "Jump-to-definition should not work on float literals")
|
|
|
|
// Test nil literal
|
|
let nilResponse = try await testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["5️⃣"])
|
|
)
|
|
XCTAssertNil(nilResponse, "Jump-to-definition should not work on nil literals")
|
|
}
|
|
|
|
func testDefinitionInsideLiteralsShouldStillWork() async throws {
|
|
let testClient = try await TestSourceKitLSPClient()
|
|
let uri = DocumentURI(for: .swift)
|
|
|
|
let positions = testClient.openDocument(
|
|
#"""
|
|
let name = "Ayman"
|
|
let greeting = "Hello \(1️⃣name)"
|
|
let items = [2️⃣name, "other"]
|
|
"""#,
|
|
uri: uri
|
|
)
|
|
|
|
// Identifier inside string interpolation - should work
|
|
let interpolationResponse = try await testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["1️⃣"])
|
|
)
|
|
XCTAssertNotNil(
|
|
interpolationResponse,
|
|
"Jump-to-definition should work for identifiers inside string interpolation"
|
|
)
|
|
|
|
// Identifier inside array literal - should work
|
|
let arrayResponse = try await testClient.send(
|
|
DefinitionRequest(textDocument: TextDocumentIdentifier(uri), position: positions["2️⃣"])
|
|
)
|
|
XCTAssertNotNil(
|
|
arrayResponse,
|
|
"Jump-to-definition should work for identifiers inside array literals"
|
|
)
|
|
}
|
|
}
|