Skip to content

Commit cfc80b3

Browse files
Merge branch 'feature/q-lsp' into samgst/q-lsp-did-rename-spec-update
2 parents 62fdabe + 5f752ca commit cfc80b3

File tree

9 files changed

+136
-78
lines changed

9 files changed

+136
-78
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "bugfix",
3+
"description" : "/review: Respect user option to allow code suggestions with references"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "feature",
3+
"description" : "/review: automatically generate fix without clicking Generate Fix button"
4+
}

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/AmazonQCodeFixSession.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import software.amazon.awssdk.services.codewhispererruntime.model.GetCodeFixJobR
1414
import software.amazon.awssdk.services.codewhispererruntime.model.GetCodeFixJobResponse
1515
import software.amazon.awssdk.services.codewhispererruntime.model.Position
1616
import software.amazon.awssdk.services.codewhispererruntime.model.Range
17+
import software.amazon.awssdk.services.codewhispererruntime.model.RecommendationsWithReferencesPreference
1718
import software.amazon.awssdk.services.codewhispererruntime.model.StartCodeFixJobRequest
1819
import software.amazon.awssdk.services.codewhispererruntime.model.StartCodeFixJobResponse
1920
import software.amazon.awssdk.services.codewhispererruntime.model.UploadContext
@@ -28,6 +29,7 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWh
2829
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants
2930
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererZipUploadManager
3031
import software.aws.toolkits.jetbrains.services.codewhisperer.util.getTelemetryErrorMessage
32+
import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings
3133
import software.aws.toolkits.resources.message
3234
import java.io.File
3335
import java.nio.file.Path
@@ -161,12 +163,19 @@ class AmazonQCodeFixSession(val project: Project) {
161163
codeFixName: String? = null,
162164
ruleId: String? = null,
163165
): StartCodeFixJobResponse {
166+
val includeCodeWithReference = if (CodeWhispererSettings.getInstance().isIncludeCodeWithReference()) {
167+
RecommendationsWithReferencesPreference.ALLOW
168+
} else {
169+
RecommendationsWithReferencesPreference.BLOCK
170+
}
171+
164172
val request = StartCodeFixJobRequest.builder()
165173
.uploadId(uploadId)
166174
.snippetRange(snippetRange)
167175
.codeFixName(codeFixName)
168176
.ruleId(ruleId)
169177
.description(description)
178+
.referenceTrackerConfiguration { it.recommendationsWithReferences(includeCodeWithReference) }
170179
.build()
171180

172181
return try {

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanIssueDetailsPanel.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,5 +333,10 @@ internal class CodeWhispererCodeScanIssueDetailsPanel(
333333
add(BorderLayout.SOUTH, buttonPane)
334334
isVisible = true
335335
revalidate()
336+
if (issue.suggestedFixes.isEmpty()) {
337+
defaultScope.launch {
338+
handleGenerateFix(issue)
339+
}
340+
}
336341
}
337342
}

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandler.kt

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,27 @@ class TextDocumentServiceHandler(
5252
FileDocumentManagerListener.TOPIC,
5353
this
5454
)
55+
56+
// open files on startup
57+
val fileEditorManager = FileEditorManager.getInstance(project)
58+
fileEditorManager.openFiles.forEach { file ->
59+
handleFileOpened(file)
60+
}
61+
}
62+
63+
private fun handleFileOpened(file: VirtualFile) {
64+
AmazonQLspService.executeIfRunning(project) { languageServer ->
65+
toUriString(file)?.let { uri ->
66+
languageServer.textDocumentService.didOpen(
67+
DidOpenTextDocumentParams().apply {
68+
textDocument = TextDocumentItem().apply {
69+
this.uri = uri
70+
text = file.inputStream.readAllBytes().decodeToString()
71+
}
72+
}
73+
)
74+
}
75+
}
5576
}
5677

5778
override fun beforeDocumentSaving(document: Document) {
@@ -99,18 +120,7 @@ class TextDocumentServiceHandler(
99120
source: FileEditorManager,
100121
file: VirtualFile,
101122
) {
102-
AmazonQLspService.executeIfRunning(project) { languageServer ->
103-
toUriString(file)?.let { uri ->
104-
languageServer.textDocumentService.didOpen(
105-
DidOpenTextDocumentParams().apply {
106-
textDocument = TextDocumentItem().apply {
107-
this.uri = uri
108-
text = file.inputStream.readAllBytes().decodeToString()
109-
}
110-
}
111-
)
112-
}
113-
}
123+
handleFileOpened(file)
114124
}
115125

116126
override fun fileClosed(

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/manifest/ManifestManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import software.aws.toolkits.jetbrains.core.getTextFromUrl
1515

1616
class ManifestManager {
1717
private val cloudFrontUrl = "https://aws-toolkit-language-servers.amazonaws.com/q-context/manifest.json"
18-
val currentVersion = "0.1.32"
18+
val currentVersion = "0.1.46"
1919
val currentOs = getOs()
2020
private val arch = CpuArch.CURRENT
2121
private val mapper = jacksonObjectMapper().apply { configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) }

plugins/amazonq/shared/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/lsp/textdocument/TextDocumentServiceHandlerTest.kt

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.intellij.openapi.application.ApplicationManager
99
import com.intellij.openapi.components.serviceIfCreated
1010
import com.intellij.openapi.editor.Document
1111
import com.intellij.openapi.fileEditor.FileDocumentManager
12+
import com.intellij.openapi.fileEditor.FileEditorManager
1213
import com.intellij.openapi.project.Project
1314
import com.intellij.openapi.vfs.VirtualFile
1415
import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent
@@ -24,13 +25,13 @@ import io.mockk.runs
2425
import io.mockk.slot
2526
import io.mockk.verify
2627
import kotlinx.coroutines.test.runTest
28+
import org.assertj.core.api.Assertions.assertThat
2729
import org.eclipse.lsp4j.DidChangeTextDocumentParams
2830
import org.eclipse.lsp4j.DidCloseTextDocumentParams
2931
import org.eclipse.lsp4j.DidOpenTextDocumentParams
3032
import org.eclipse.lsp4j.DidSaveTextDocumentParams
3133
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage
3234
import org.eclipse.lsp4j.services.TextDocumentService
33-
import org.junit.Assert.assertEquals
3435
import org.junit.Before
3536
import org.junit.Test
3637
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLanguageServer
@@ -43,6 +44,7 @@ import java.util.concurrent.CompletableFuture
4344

4445
class TextDocumentServiceHandlerTest {
4546
private lateinit var project: Project
47+
private lateinit var mockFileEditorManager: FileEditorManager
4648
private lateinit var mockLanguageServer: AmazonQLanguageServer
4749
private lateinit var mockTextDocumentService: TextDocumentService
4850
private lateinit var sut: TextDocumentServiceHandler
@@ -90,6 +92,11 @@ class TextDocumentServiceHandlerTest {
9092
every { messageBus.connect(any<Disposable>()) } returns mockConnection
9193
every { mockConnection.subscribe(any(), any()) } just runs
9294

95+
// Mock FileEditorManager
96+
mockFileEditorManager = mockk<FileEditorManager>()
97+
every { mockFileEditorManager.openFiles } returns emptyArray()
98+
every { project.getService(FileEditorManager::class.java) } returns mockFileEditorManager
99+
93100
sut = TextDocumentServiceHandler(project, mockk())
94101
}
95102

@@ -120,12 +127,31 @@ class TextDocumentServiceHandlerTest {
120127
verify { mockTextDocumentService.didSave(capture(paramsSlot)) }
121128

122129
with(paramsSlot.captured) {
123-
assertEquals(normalizeFileUri(uri.toString()), textDocument.uri)
124-
assertEquals("test content", text)
130+
assertThat(textDocument.uri).isEqualTo(normalizeFileUri(uri.toString()))
131+
assertThat(text).isEqualTo("test content")
125132
}
126133
}
127134
}
128135

136+
@Test
137+
fun `didOpen runs on service init`() = runTest {
138+
val uri = URI.create("file:///test/path/file.txt")
139+
val content = "test content"
140+
val file = createMockVirtualFile(uri, content)
141+
142+
every { mockFileEditorManager.openFiles } returns arrayOf(file)
143+
144+
sut = TextDocumentServiceHandler(project, mockk())
145+
146+
val paramsSlot = slot<DidOpenTextDocumentParams>()
147+
verify { mockTextDocumentService.didOpen(capture(paramsSlot)) }
148+
149+
with(paramsSlot.captured.textDocument) {
150+
assertThat(this.uri).isEqualTo(normalizeFileUri(uri.toString()))
151+
assertThat(text).isEqualTo(content)
152+
}
153+
}
154+
129155
@Test
130156
fun `didOpen runs on fileOpened`() = runTest {
131157
// Create test file
@@ -142,8 +168,8 @@ class TextDocumentServiceHandlerTest {
142168
verify { mockTextDocumentService.didOpen(capture(paramsSlot)) }
143169

144170
with(paramsSlot.captured.textDocument) {
145-
assertEquals(normalizeFileUri(uri.toString()), this.uri)
146-
assertEquals(content, text)
171+
assertThat(this.uri).isEqualTo(normalizeFileUri(uri.toString()))
172+
assertThat(text).isEqualTo(content)
147173
}
148174
}
149175

@@ -157,7 +183,7 @@ class TextDocumentServiceHandlerTest {
157183
val paramsSlot = slot<DidCloseTextDocumentParams>()
158184
verify { mockTextDocumentService.didClose(capture(paramsSlot)) }
159185

160-
assertEquals(normalizeFileUri(uri.toString()), paramsSlot.captured.textDocument.uri)
186+
assertThat(paramsSlot.captured.textDocument.uri).isEqualTo(normalizeFileUri(uri.toString()))
161187
}
162188

163189
@Test
@@ -191,9 +217,9 @@ class TextDocumentServiceHandlerTest {
191217
verify { mockTextDocumentService.didChange(capture(paramsSlot)) }
192218

193219
with(paramsSlot.captured) {
194-
assertEquals(normalizeFileUri(uri.toString()), textDocument.uri)
195-
assertEquals(123, textDocument.version)
196-
assertEquals("changed content", contentChanges[0].text)
220+
assertThat(textDocument.uri).isEqualTo(normalizeFileUri(uri.toString()))
221+
assertThat(textDocument.version).isEqualTo(123)
222+
assertThat(contentChanges[0].text).isEqualTo("changed content")
197223
}
198224
}
199225

plugins/amazonq/shared/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/lsp/util/WorkspaceFolderUtilTest.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import com.intellij.openapi.roots.ProjectRootManager
88
import com.intellij.openapi.vfs.VirtualFile
99
import io.mockk.every
1010
import io.mockk.mockk
11-
import org.junit.jupiter.api.Assertions.assertEquals
11+
import org.assertj.core.api.Assertions.assertThat
1212
import org.junit.jupiter.api.Test
1313
import java.net.URI
1414
import java.nio.file.Path
@@ -22,7 +22,7 @@ class WorkspaceFolderUtilTest {
2222

2323
val result = WorkspaceFolderUtil.createWorkspaceFolders(mockProject)
2424

25-
assertEquals(emptyList<VirtualFile>(), result)
25+
assertThat(result).isEqualTo(emptyList<VirtualFile>())
2626
}
2727

2828
@Test
@@ -44,11 +44,11 @@ class WorkspaceFolderUtilTest {
4444

4545
val result = WorkspaceFolderUtil.createWorkspaceFolders(mockProject)
4646

47-
assertEquals(2, result.size)
48-
assertEquals(normalizeFileUri("file:///path/to/root1"), result[0].uri)
49-
assertEquals(normalizeFileUri("file:///path/to/root2"), result[1].uri)
50-
assertEquals("root1", result[0].name)
51-
assertEquals("root2", result[1].name)
47+
assertThat(result).hasSize(2)
48+
assertThat(result[0].uri).isEqualTo(normalizeFileUri("file:///path/to/root1"))
49+
assertThat(result[1].uri).isEqualTo(normalizeFileUri("file:///path/to/root2"))
50+
assertThat(result[0].name).isEqualTo("root1")
51+
assertThat(result[1].name).isEqualTo("root2")
5252
}
5353

5454
@Test
@@ -62,7 +62,7 @@ class WorkspaceFolderUtilTest {
6262

6363
val result = WorkspaceFolderUtil.createWorkspaceFolders(mockProject)
6464

65-
assertEquals(emptyList<VirtualFile>(), result)
65+
assertThat(result).isEqualTo(emptyList<VirtualFile>())
6666
}
6767

6868
private fun createMockVirtualFile(uri: URI, name: String): VirtualFile {

0 commit comments

Comments
 (0)