@@ -5,6 +5,7 @@ package software.aws.toolkits.jetbrains.services.amazonq.webview
5
5
6
6
import com.fasterxml.jackson.databind.JsonNode
7
7
import com.fasterxml.jackson.databind.node.ObjectNode
8
+ import com.fasterxml.jackson.module.kotlin.readValue
8
9
import com.fasterxml.jackson.module.kotlin.treeToValue
9
10
import com.google.gson.Gson
10
11
import com.intellij.ide.BrowserUtil
@@ -34,6 +35,7 @@ import org.cef.browser.CefBrowser
34
35
import org.eclipse.lsp4j.TextDocumentIdentifier
35
36
import org.eclipse.lsp4j.jsonrpc.ResponseErrorException
36
37
import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode
38
+ import org.intellij.lang.annotations.Language
37
39
import software.aws.toolkits.core.utils.error
38
40
import software.aws.toolkits.core.utils.getLogger
39
41
import software.aws.toolkits.core.utils.info
@@ -115,9 +117,6 @@ import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.auth.isFeature
115
117
import software.aws.toolkits.jetbrains.services.codemodernizer.utils.isCodeTransformAvailable
116
118
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhispererCodeScanIssue
117
119
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhispererCodeScanManager
118
- import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.Description
119
- import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.Recommendation
120
- import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.SuggestedFix
121
120
import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererConfigurable
122
121
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants
123
122
import software.aws.toolkits.jetbrains.settings.MeetQSettings
@@ -581,32 +580,6 @@ class BrowserConnector(
581
580
}
582
581
}
583
582
584
- data class FlareCodeScanIssue (
585
- val startLine : Int ,
586
- val endLine : Int ,
587
- val comment : String? ,
588
- val title : String ,
589
- val description : Description ,
590
- val detectorId : String ,
591
- val detectorName : String ,
592
- val findingId : String ,
593
- val ruleId : String? ,
594
- val relatedVulnerabilities : List <String >,
595
- val severity : String ,
596
- val recommendation : Recommendation ,
597
- val suggestedFixes : List <SuggestedFix >,
598
- val scanJobId : String ,
599
- val language : String ,
600
- val autoDetected : Boolean ,
601
- val filePath : String ,
602
- val findingContext : String ,
603
- )
604
-
605
- data class AggregatedCodeScanIssue (
606
- val filePath : String ,
607
- val issues : List <FlareCodeScanIssue >,
608
- )
609
-
610
583
private fun showResult (
611
584
result : CompletableFuture <String >,
612
585
partialResultToken : String ,
@@ -620,14 +593,13 @@ class BrowserConnector(
620
593
throw error
621
594
}
622
595
chatCommunicationManager.removePartialChatMessage(partialResultToken)
623
- val decryptedMessage = Gson ().fromJson(value?.let { encryptionManager?.decrypt(it) }.orEmpty(), Map ::class .java)
624
- as Map <String , * >
596
+ val decryptedMessage = value?.let { encryptionManager?.decrypt(it) }.orEmpty()
625
597
parseFindingsMessages(decryptedMessage)
626
598
627
599
val messageToChat = ChatCommunicationManager .convertToJsonToSendToChat(
628
600
SEND_CHAT_COMMAND_PROMPT ,
629
601
tabId,
630
- Gson ().toJson( decryptedMessage) ,
602
+ decryptedMessage,
631
603
isPartialResult = false
632
604
)
633
605
browser.postChat(messageToChat)
@@ -641,26 +613,23 @@ class BrowserConnector(
641
613
}
642
614
}
643
615
644
- fun parseFindingsMessages (messagesMap : Map <String , * >) {
616
+ fun deserializeFindings (@Language(" JSON" ) responsePayload : String ): List <FlareAggregatedFindings > {
617
+ val additionalMessages = serializer.objectMapper.readValue<FlareAdditionalMessages >(responsePayload).additionalMessages
618
+ ? : return emptyList()
619
+
620
+ return additionalMessages.filter { message ->
621
+ message.messageId.endsWith(CODE_REVIEW_FINDINGS_SUFFIX ) ||
622
+ message.messageId.endsWith(DISPLAY_FINDINGS_SUFFIX )
623
+ }
624
+ }
625
+
626
+ fun parseFindingsMessages (@Language(" JSON" ) responsePayload : String ) {
645
627
try {
646
- val additionalMessages = messagesMap[" additionalMessages" ] as ? MutableList <Map <String , Any >>
647
- val findingsMessages = additionalMessages?.filter { message ->
648
- if (message.contains(" messageId" )) {
649
- (message[" messageId" ] as String ).endsWith(CODE_REVIEW_FINDINGS_SUFFIX ) ||
650
- (message[" messageId" ] as String ).endsWith(DISPLAY_FINDINGS_SUFFIX )
651
- } else {
652
- false
653
- }
654
- }
628
+ val findings = deserializeFindings(responsePayload)
655
629
val scannedFiles = mutableListOf<VirtualFile >()
656
- if (findingsMessages != null ) {
657
- for (findingsMessage in findingsMessages) {
658
- additionalMessages.remove(findingsMessage)
659
- val gson = Gson ()
660
- val jsonFindings = gson.fromJson(findingsMessage[" body" ] as String , List ::class .java)
661
- val mappedFindings = mutableListOf<CodeWhispererCodeScanIssue >()
662
- for (aggregatedIssueUnformatted in jsonFindings) {
663
- val aggregatedIssue = gson.fromJson(gson.toJson(aggregatedIssueUnformatted), AggregatedCodeScanIssue ::class .java)
630
+ val mappedFindings = buildList {
631
+ for (finding in findings) {
632
+ for (aggregatedIssue in finding.body) {
664
633
val file = LocalFileSystem .getInstance().findFileByIoFile(
665
634
Path .of(aggregatedIssue.filePath).toFile()
666
635
)
@@ -677,7 +646,8 @@ class BrowserConnector(
677
646
if (isIssueIgnored) {
678
647
continue
679
648
}
680
- mappedFindings.add(
649
+
650
+ add(
681
651
CodeWhispererCodeScanIssue (
682
652
startLine = issue.startLine,
683
653
startCol = 1 ,
@@ -705,18 +675,20 @@ class BrowserConnector(
705
675
}
706
676
}
707
677
}
708
-
709
- CodeWhispererCodeScanManager .getInstance(project)
710
- .addOnDemandIssues(
711
- mappedFindings,
712
- scannedFiles,
713
- CodeWhispererConstants .CodeAnalysisScope .AGENTIC
714
- )
715
- CodeWhispererCodeScanManager .getInstance(project).showCodeScanUI()
716
678
}
717
679
}
680
+
681
+ if (mappedFindings.isNotEmpty()) {
682
+ CodeWhispererCodeScanManager .getInstance(project)
683
+ .addOnDemandIssues(
684
+ mappedFindings,
685
+ scannedFiles,
686
+ CodeWhispererConstants .CodeAnalysisScope .AGENTIC
687
+ )
688
+ CodeWhispererCodeScanManager .getInstance(project).showCodeScanUI()
689
+ }
718
690
} catch (e: Exception ) {
719
- LOG .error { " Failed to parse findings message $e " }
691
+ LOG .error(e) { " Failed to parse findings message" }
720
692
}
721
693
}
722
694
0 commit comments