Skip to content

Report codeActions for fixIts produced by swift syntax #941

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

joehsieh
Copy link
Contributor

@joehsieh joehsieh commented Oct 27, 2023

still WIP, i'm trying to figure out how to write tests for this change.

Implemented an initializer of CodeAction with the FixIt from swift-syntax and added a test for it.

@ahoppen
Copy link
Member

ahoppen commented Oct 27, 2023

Having an idea of how to test this is definitely not trivial, so here’s a snippet. You should then be able to write assertions to test diagnostics.

// Create a workspace with compile commands that don't contain the file we are getting diagnostics for.
// That way we have a workspace that has a build system (and thus doesn't promote settings from the fallback build
// system to be non-fallback settings) but doesn't have build settings for the file being tested. Thus, we generate
// diagnostics from the built-in SwiftParser.
let ws = try await MultiFileTestWorkspace(files: [
  "test.swift": "let var = 2",
  "compile_commands.json": "[]"
])

let (uri, _) = try ws.openDocument("test.swift")

let diagnostics = try await ws.testClient.send(DocumentDiagnosticsRequest(textDocument: TextDocumentIdentifier(uri)))

@ahoppen
Copy link
Member

ahoppen commented Oct 27, 2023

And thanks a lot for working on this @joehsieh!

@joehsieh joehsieh force-pushed the report-codeActions-for-fix-its-produced-by-swift-syntax branch 2 times, most recently from 15158e3 to 8a4bc54 Compare October 30, 2023 14:56
Package.swift Outdated
@@ -337,7 +337,8 @@ if useLocalDependencies {
.package(url: "https://github.com/apple/swift-package-manager.git", branch: relatedDependenciesBranch),
.package(url: "https://github.com/apple/swift-tools-support-core.git", branch: relatedDependenciesBranch),
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.2"),
.package(url: "https://github.com/apple/swift-syntax.git", branch: relatedDependenciesBranch),
// .package(url: "https://github.com/apple/swift-syntax.git", branch: relatedDependenciesBranch),
.package(url: "https://github.com/joehsieh/swift-syntax", branch: "add-fix-it-extesion"),
Copy link
Contributor Author

@joehsieh joehsieh Oct 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: this change will be reverted once this PR is merged.

@joehsieh joehsieh marked this pull request as ready for review October 30, 2023 15:00
)
}

private static func generateTitle(with edits: [TextEdit], snapshot: DocumentSnapshot) -> String? {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick, I would name this without generate. Since this is side-effect free, I don’t think the function name needs a result and generate basically just says that the function is returning something, which is obvious from the result type.

Suggested change
private static func generateTitle(with edits: [TextEdit], snapshot: DocumentSnapshot) -> String? {
private static func title(for edits: [TextEdit], in snapshot: DocumentSnapshot) -> String? {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right. let me update it.

edit: WorkspaceEdit(
changes: [
uri : [
TextEdit(range: Position(line: 0, utf16index: 9)..<Position(line: 0, utf16index: 15), newText: "Multiident "),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you use location markers here instead of hardcoded line-column offsets. We aren’t very good about it in the codebase yet as I only introduced the concept of location markers in the last couple of weeks but it’s generally proffered because of the same reasons that I mentioned in your swift-syntax PR.

Here’s an example of how to use the location markers.

https://github.com/apple/sourcekit-lsp/blob/9f7ff0891a115f1ae056348744abffd0452806e5/Tests/SourceKitLSPTests/LocalClangTests.swift#L246-L264

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it, it makes sense to use location markers instead. i'll update the code.


let expectedCodeActions = [
CodeAction(
title: "Replace \'Multi \' with \'Multiident \'...",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don’t need to escape the ' in Swift string literals.

Comment on lines 445 to 448
guard let codeActions = diagnostic.codeActions else {
XCTFail("Expected non-empty codeActions")
return
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could just use XCTUnwrap

Suggested change
guard let codeActions = diagnostic.codeActions else {
XCTFail("Expected non-empty codeActions")
return
}
let codeActions = try XCTUnwrap(diagnostic.codeAction)

@joehsieh joehsieh requested a review from ahoppen October 31, 2023 13:05

func testCodeActionForFixItsProducedBySwiftSyntax() async throws {
let ws = try await MultiFileTestWorkspace(files: [
"test.swift": "protocol 0️⃣Multi 1️⃣ident 2️⃣{}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick similar to the PR in swift-syntax: We usually start counting the location markers at 0. Would be nice to be consistent here.

Comment on lines 71 to 73
guard let generatedTitle = Self.title(for: textEdits, in: snapshot) else {
return nil
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix-Its from swift-syntax always have a message (fixIt.message.message I think) and I think we should be using that instead of synthesizing a title here. I think the extraction of title(for:in:) makes sense regardless though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i tried to use fixIt.message.message instead of title(for:in:), but it failed the test, so we might not be able to do it.

Expected: 
"Replace 'Multi ' with 'Multiident '..."
"Replace 'Multi ' with 'MultiIdent '..."

Actual:
"join the identifiers together",
"join the identifiers together with camel-case"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can’t you just update the test case to expect join the identifiers together?

Also, it would be good to uppercase the first character of the diagnostic, similar to what I did here: #784

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right, i put the code protocol Multi ident {} in a swift playground.
the error message was

Join the identifiers together
Join the identifiers together with camel-case

let me correct it.

@joehsieh joehsieh force-pushed the report-codeActions-for-fix-its-produced-by-swift-syntax branch from 5b5e295 to 33b4950 Compare November 2, 2023 01:10
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. We just need to wait to get swiftlang/swift-syntax#2314 in and revert the change to the package manifest.

When you do that, could you squash your commits? It makes for a nicer Git history.

@joehsieh
Copy link
Contributor Author

joehsieh commented Nov 2, 2023

Got it, i'll do it.
btw, for sourcekit-lsp, do we have a similar way to format the code like what we did for swift-syntax?

in the meantime, i'm trying to refine below command and put it in a git hook

find . -type f -name "*.swift" -exec swift-format format -i {} \;

@ahoppen
Copy link
Member

ahoppen commented Nov 6, 2023

I was thinking about integrating the swift-format command plugin into sourcekit-lsp. That way you should be able to run swift-format e.g. from Xcode. But I haven’t had time to look into it yet. If you want, you could try that.

@joehsieh
Copy link
Contributor Author

joehsieh commented Nov 7, 2023

thanks for the reminder. i found a vscode plugin for swift-format.
https://marketplace.visualstudio.com/items?itemName=vknabel.vscode-apple-swift-format&ssr=false#overview
even though i need to click a button to format the code by myself...

for the plugin of Xcode, it looks like there is a good one. https://github.com/nicklockwood/SwiftFormat#what-is-this
but I haven't tried it.

Finetune the code

Finetune the code

Finetune the code

Update the code per comments

Use location marker instead of hard coded indexes

Update the test to align the code convention

Rename a variable

Correct unit tests

Format the code

Update Package.swift
@joehsieh joehsieh force-pushed the report-codeActions-for-fix-its-produced-by-swift-syntax branch from 13feeb5 to a095810 Compare November 8, 2023 09:12
@joehsieh joehsieh requested a review from ahoppen November 8, 2023 09:14
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let’s get this in 🎉

@ahoppen
Copy link
Member

ahoppen commented Nov 8, 2023

@swift-ci Please test

@ahoppen ahoppen enabled auto-merge November 8, 2023 15:25
@ahoppen
Copy link
Member

ahoppen commented Nov 8, 2023

@swift-ci Please test Windows

@ahoppen
Copy link
Member

ahoppen commented Nov 8, 2023

Windows failure is unrelated to your PR.

@shahmishal
Copy link
Member

@swift-ci Please test Windows

1 similar comment
@ahoppen
Copy link
Member

ahoppen commented Nov 9, 2023

@swift-ci Please test Windows

@ahoppen ahoppen merged commit 113219a into swiftlang:main Nov 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants