private async acceptCode()

in packages/core/src/amazonqTest/chat/controller/controller.ts [748:906]


    private async acceptCode(message: any) {
        const session = this.sessionStorage.getSession()
        session.acceptedJobId = session.listOfTestGenerationJobId[session.listOfTestGenerationJobId.length - 1]
        const filePath = session.generatedFilePath
        const absolutePath = path.join(session.projectRootPath, filePath)
        const fileExists = await fs.existsFile(absolutePath)
        const buildCommand = session.updatedBuildCommands?.join(' ')

        const tempFilePath = path.join(this.tempResultDirPath, 'resultArtifacts', filePath)
        const updatedContent = await fs.readFileText(tempFilePath)
        let acceptedLines = updatedContent.split('\n').length
        let acceptedChars = updatedContent.length
        if (fileExists) {
            const originalContent = await fs.readFileText(absolutePath)
            acceptedLines -= originalContent.split('\n').length
            acceptedLines = acceptedLines < 0 ? 0 : acceptedLines
            acceptedChars -= originalContent.length
            acceptedChars = acceptedChars < 0 ? 0 : acceptedChars
            UserWrittenCodeTracker.instance.onQStartsMakingEdits()
            const document = await vscode.workspace.openTextDocument(absolutePath)
            await applyChanges(
                document,
                new vscode.Range(document.lineAt(0).range.start, document.lineAt(document.lineCount - 1).range.end),
                updatedContent
            )
            UserWrittenCodeTracker.instance.onQFinishesEdits()
        } else {
            await fs.writeFile(absolutePath, updatedContent)
        }
        session.charsOfCodeAccepted = acceptedChars
        session.linesOfCodeAccepted = acceptedLines

        // add accepted references to reference log, if any
        const fileName = path.basename(session.generatedFilePath)
        const time = new Date().toLocaleString()
        // TODO: this is duplicated in basicCommands.ts for scan (codewhisperer). Fix this later.
        for (const reference of session.references) {
            getLogger().debug('Processing reference: %O', reference)
            // Log values for debugging
            getLogger().debug('updatedContent: %s', updatedContent)
            getLogger().debug(
                'start: %d, end: %d',
                reference.recommendationContentSpan?.start,
                reference.recommendationContentSpan?.end
            )
            // given a start and end index, figure out which line number they belong to when splitting a string on /n characters
            const getLineNumber = (content: string, index: number): number => {
                const lines = content.slice(0, index).split('\n')
                return lines.length
            }
            const startLine = getLineNumber(updatedContent, reference.recommendationContentSpan!.start)
            const endLine = getLineNumber(updatedContent, reference.recommendationContentSpan!.end)
            getLogger().debug('startLine: %d, endLine: %d', startLine, endLine)

            const code = updatedContent.slice(
                reference.recommendationContentSpan?.start,
                reference.recommendationContentSpan?.end
            )
            getLogger().debug('Extracted code slice: %s', code)
            const referenceLog =
                `[${time}] Accepted recommendation ` +
                referenceLogText(
                    `<br><code>${code}</code><br>`,
                    reference.licenseName!,
                    reference.repository!,
                    fileName,
                    startLine === endLine ? `(line at ${startLine})` : `(lines from ${startLine} to ${endLine})`
                ) +
                '<br>'
            getLogger().debug('Adding reference log: %s', referenceLog)
            ReferenceLogViewProvider.instance.addReferenceLog(referenceLog)
        }

        // TODO: see if there's a better way to check if active file is a diff
        if (vscode.window.tabGroups.activeTabGroup.activeTab?.label.includes(amazonQTabSuffix)) {
            await vscode.commands.executeCommand('workbench.action.closeActiveEditor')
        }
        const document = await vscode.workspace.openTextDocument(absolutePath)
        await vscode.window.showTextDocument(document)
        // TODO: send the message once again once build is enabled
        // this.messenger.sendMessage('Accepted', message.tabID, 'prompt')
        telemetry.ui_click.emit({ elementId: 'unitTestGeneration_acceptDiff' })

        getLogger().info(
            `Generated unit tests are accepted for ${session.fileLanguage ?? 'plaintext'} language with jobId: ${session.listOfTestGenerationJobId[0]}, jobGroupName: ${session.testGenerationJobGroupName}, result: Succeeded`
        )
        TelemetryHelper.instance.sendTestGenerationToolkitEvent(
            session,
            true,
            true,
            'Succeeded',
            session.startTestGenerationRequestId,
            session.latencyOfTestGeneration,
            undefined,
            session.isCodeBlockSelected,
            session.artifactsUploadDuration,
            session.srcPayloadSize,
            session.srcZipFileSize,
            session.charsOfCodeAccepted,
            session.numberOfTestsGenerated,
            session.linesOfCodeAccepted,
            session.charsOfCodeGenerated,
            session.numberOfTestsGenerated,
            session.linesOfCodeGenerated,
            undefined,
            'ACCEPTED'
        )

        await this.endSession(message, FollowUpTypes.SkipBuildAndFinish)
        return

        if (session.listOfTestGenerationJobId.length === 1) {
            this.startInitialBuild(message)
            this.messenger.sendChatInputEnabled(message.tabID, false)
        } else if (session.listOfTestGenerationJobId.length < 4) {
            const remainingIterations = 4 - session.listOfTestGenerationJobId.length

            let userMessage = 'Would you like Amazon Q to build and execute again, and fix errors?'
            if (buildCommand) {
                userMessage += ` I will be running this build command: \`${buildCommand}\``
            }
            userMessage += `\nYou have ${remainingIterations} iteration${remainingIterations > 1 ? 's' : ''} left.`

            const followUps: FollowUps = {
                text: '',
                options: [
                    {
                        pillText: `Rebuild`,
                        type: FollowUpTypes.ContinueBuildAndExecute,
                        status: 'primary',
                    },
                    {
                        pillText: `Skip and finish`,
                        type: FollowUpTypes.SkipBuildAndFinish,
                        status: 'primary',
                    },
                ],
            }
            this.messenger.sendBuildProgressMessage({
                tabID: message.tabID,
                messageType: 'answer',
                codeGenerationId: '',
                message: userMessage,
                canBeVoted: false,
                messageId: '',
                followUps: followUps,
            })
            this.messenger.sendChatInputEnabled(message.tabID, false)
        } else {
            this.sessionStorage.getSession().listOfTestGenerationJobId = []
            this.messenger.sendMessage(
                'You have gone through both iterations and this unit test generation workflow is complete.',
                message.tabID,
                'answer'
            )
            await this.sessionCleanUp()
        }
        await fs.delete(this.tempResultDirPath, { recursive: true })
    }