Skip to content

Commit 3e16f5a

Browse files
committed
Merge remote-tracking branch 'upstream/master' into repomap
2 parents 0d19e53 + d2cde47 commit 3e16f5a

File tree

9 files changed

+56
-22
lines changed

9 files changed

+56
-22
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "Fix inline completion supplementalContext length exceeding maximum in certain cases"
4+
}

packages/amazonq/test/unit/codewhisperer/util/crossFileContextUtil.test.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ import * as FakeTimers from '@sinonjs/fake-timers'
88
import * as vscode from 'vscode'
99
import * as sinon from 'sinon'
1010
import * as crossFile from 'aws-core-vscode/codewhisperer'
11-
import { aStringWithLineCount, createMockTextEditor, installFakeClock } from 'aws-core-vscode/test'
11+
import {
12+
aLongStringWithLineCount,
13+
aStringWithLineCount,
14+
createMockTextEditor,
15+
installFakeClock,
16+
} from 'aws-core-vscode/test'
1217
import { FeatureConfigProvider, crossFileContextConfig } from 'aws-core-vscode/codewhisperer'
1318
import {
1419
assertTabCount,
@@ -71,8 +76,8 @@ describe('crossFileContextUtil', function () {
7176
assert.strictEqual(actual.supplementalContextItems[2].content.split('\n').length, 50)
7277
})
7378

74-
it('for t1 group, should return repomap + opentabs context', async function () {
75-
await toTextEditor(aStringWithLineCount(200), 'CrossFile.java', tempFolder, { preview: false })
79+
it('for t1 group, should return repomap + opentabs context, should not exceed 20k total length', async function () {
80+
await toTextEditor(aLongStringWithLineCount(200), 'CrossFile.java', tempFolder, { preview: false })
7681
const myCurrentEditor = await toTextEditor('', 'TargetFile.java', tempFolder, {
7782
preview: false,
7883
})
@@ -85,25 +90,23 @@ describe('crossFileContextUtil', function () {
8590
.withArgs(sinon.match.any, sinon.match.any, 'codemap')
8691
.resolves([
8792
{
88-
content: 'foo',
93+
content: 'foo'.repeat(3000),
8994
score: 0,
9095
filePath: 'q-inline',
9196
},
9297
])
9398

9499
const actual = await crossFile.fetchSupplementalContextForSrc(myCurrentEditor, fakeCancellationToken)
95100
assert.ok(actual)
96-
assert.strictEqual(actual.supplementalContextItems.length, 4)
101+
assert.strictEqual(actual.supplementalContextItems.length, 3)
97102
assert.strictEqual(actual?.strategy, 'codemap')
98103
assert.deepEqual(actual?.supplementalContextItems[0], {
99-
content: 'foo',
104+
content: 'foo'.repeat(3000),
100105
score: 0,
101106
filePath: 'q-inline',
102107
})
103-
104108
assert.strictEqual(actual.supplementalContextItems[1].content.split('\n').length, 50)
105109
assert.strictEqual(actual.supplementalContextItems[2].content.split('\n').length, 50)
106-
assert.strictEqual(actual.supplementalContextItems[3].content.split('\n').length, 50)
107110
})
108111

109112
it.skip('for t2 group, should return global bm25 context and no repomap', async function () {

packages/core/src/codewhisperer/commands/startTransformByQ.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -654,14 +654,14 @@ export async function getValidSQLConversionCandidateProjects() {
654654
let resultLog = ''
655655
for (const project of javaProjects) {
656656
// as long as at least one of these strings is found, project contains embedded SQL statements
657-
const searchStrings = ['oracle.jdbc.OracleDriver', 'jdbc:oracle:thin:@', 'jdbc:oracle:oci:@', 'jdbc:odbc:']
657+
const searchStrings = ['oracle.jdbc.', 'jdbc:oracle:', 'jdbc:odbc:']
658658
for (const str of searchStrings) {
659659
const spawnResult = await findStringInDirectory(str, project.path)
660660
// just for telemetry purposes
661661
if (spawnResult.error || spawnResult.stderr) {
662-
resultLog += `search failed: ${JSON.stringify(spawnResult)}`
662+
resultLog += `search error: ${JSON.stringify(spawnResult)}--`
663663
} else {
664-
resultLog += `search succeeded: ${spawnResult.exitCode}`
664+
resultLog += `search complete (exit code: ${spawnResult.exitCode})--`
665665
}
666666
getLogger().info(`CodeTransformation: searching for ${str} in ${project.path}, result = ${resultLog}`)
667667
if (spawnResult.exitCode === 0) {

packages/core/src/codewhisperer/models/constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export const lineBreakWin = '\r\n'
8484

8585
export const supplementalContextTimeoutInMs = 100
8686

87+
export const supplementalContextMaxTotalLength = 20480
8788
/**
8889
* Ux of recommendations
8990
*/
@@ -501,7 +502,7 @@ export const codeTransformLocThreshold = 100000
501502
export const jobStartedChatMessage =
502503
'I am starting to transform your code. It can take 10 to 30 minutes to upgrade your code, depending on the size of your project. To monitor progress, go to the Transformation Hub. If I run into any issues, I might pause the transformation to get input from you on how to proceed.'
503504

504-
export const chooseTransformationObjective = `I can help you with the following tasks:\n- Upgrade your Java 8 and Java 11 codebases to Java 17, or upgrade Java 17 code with up to date libraries and other dependencies.\n- Convert embedded SQL code for Oracle to PostgreSQL database migrations in AWS DMS.\n\nWhat would you like to do? You can enter "language upgrade" or "sql conversion".`
505+
export const chooseTransformationObjective = `I can help you with the following tasks:\n- Upgrade your Java 8 and Java 11 codebases to Java 17, or upgrade Java 17 code with up to date libraries and other dependencies.\n- Convert embedded SQL code for Oracle to PostgreSQL database migrations in AWS DMS. [Learn more](https://docs.aws.amazon.com/dms/latest/userguide/schema-conversion-embedded-sql.html).\n\nWhat would you like to do? You can enter "language upgrade" or "sql conversion".`
505506

506507
export const chooseTransformationObjectivePlaceholder = 'Enter "language upgrade" or "sql conversion"'
507508

packages/core/src/codewhisperer/service/testGenHandler.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ export async function exportResultsArchive(
231231
const zip = new AdmZip(pathToArchive)
232232
zip.extractAllTo(pathToArchiveDir, true)
233233

234-
const session = ChatSessionManager.Instance.getSession()
235234
const testFilePathFromResponse = session?.shortAnswer?.testFilePath
236235
const testFilePath = testFilePathFromResponse
237236
? testFilePathFromResponse.split('/').slice(1).join('/') // remove the project name

packages/core/src/codewhisperer/util/supplementalContext/crossFileContextUtil.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ import * as vscode from 'vscode'
77
import { FeatureConfigProvider, fs } from '../../../shared'
88
import path = require('path')
99
import { BM25Document, BM25Okapi } from './rankBm25'
10-
import { crossFileContextConfig, supplementalContextTimeoutInMs } from '../../models/constants'
10+
import {
11+
crossFileContextConfig,
12+
supplementalContextTimeoutInMs,
13+
supplementalContextMaxTotalLength,
14+
} from '../../models/constants'
1115
import { isTestFile } from './codeParsingUtil'
1216
import { getFileDistance } from '../../../shared/filesystemUtilities'
1317
import { getOpenFilesInWindow } from '../../../shared/utilities/editorUtilities'
@@ -99,13 +103,22 @@ export async function fetchSupplementalContextForSrc(
99103
const opentabsContext = await fetchOpentabsContext(editor, cancellationToken)
100104
const codemap = await fetchProjectContext(editor, 'codemap')
101105

106+
function addToResult(items: CodeWhispererSupplementalContextItem[]) {
107+
for (const item of items) {
108+
const curLen = result.reduce((acc, i) => acc + i.content.length, 0)
109+
if (curLen + item.content.length < supplementalContextMaxTotalLength) {
110+
result.push(item)
111+
}
112+
}
113+
}
114+
102115
if (codemap && codemap.length > 0) {
103-
result.push(...codemap)
116+
addToResult(codemap)
104117
hasCodemap = true
105118
}
106119

107120
if (opentabsContext && opentabsContext.length > 0) {
108-
result.push(...opentabsContext)
121+
addToResult(opentabsContext)
109122
hasOpentabs = true
110123
}
111124

packages/core/src/shared/wizards/wizard.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export class Wizard<TState extends Partial<Record<keyof TState, unknown>>> {
9494
private assertReady() {
9595
// Check for `false` explicity so that the base-class constructor can access `this._form`.
9696
// We want to guard against confusion when implementing a subclass, not this base-class.
97-
if (this._ready === false && this.init) {
97+
if (this._ready === false) {
9898
throw Error('run() (or init()) must be called immediately after creating the Wizard')
9999
}
100100
}
@@ -113,7 +113,7 @@ export class Wizard<TState extends Partial<Record<keyof TState, unknown>>> {
113113
return this._stepOffset[1] + this.stateController.totalSteps
114114
}
115115

116-
public get _form() {
116+
protected get _form() {
117117
this.assertReady()
118118
return this.__form
119119
}
@@ -136,14 +136,22 @@ export class Wizard<TState extends Partial<Record<keyof TState, unknown>>> {
136136
this._estimator = estimator
137137
}
138138

139-
public constructor(private readonly options: WizardOptions<TState> = {}) {
139+
public constructor(protected readonly options: WizardOptions<TState> = {}) {
140140
this.stateController = new StateMachineController(options.initState as TState)
141141
this.__form = options.initForm ?? new WizardForm()
142142
this._exitStep =
143143
options.exitPrompterProvider !== undefined ? this.createExitStep(options.exitPrompterProvider) : undefined
144144

145145
// Subclass constructor logic should live in `init()`, if it exists.
146146
this._ready = !this.init
147+
148+
if (typeof this.init === 'function') {
149+
const _init = this.init.bind(this)
150+
this.init = () => {
151+
this._ready = true
152+
return _init()
153+
}
154+
}
147155
}
148156

149157
/**
@@ -166,7 +174,6 @@ export class Wizard<TState extends Partial<Record<keyof TState, unknown>>> {
166174
if (!this._ready && this.init) {
167175
this._ready = true // Let init() use `this._form`.
168176
await this.init()
169-
delete this.init
170177
}
171178

172179
this.assignSteps()

packages/core/src/test/codewhisperer/testUtil.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,3 +329,12 @@ export function aStringWithLineCount(lineCount: number, start: number = 0): stri
329329

330330
return s.trimEnd()
331331
}
332+
333+
export function aLongStringWithLineCount(lineCount: number, start: number = 0): string {
334+
let s = ''
335+
for (let i = start; i < start + lineCount; i++) {
336+
s += `a`.repeat(100) + `line${i}\n`
337+
}
338+
339+
return s.trimEnd()
340+
}

packages/core/src/test/shared/wizards/wizardTestUtils.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,7 @@ function failIf(cond: boolean, message?: string): void {
6565
export async function createWizardTester<T extends Partial<T>>(wizard: Wizard<T> | WizardForm<T>): Promise<Tester<T>> {
6666
if (wizard instanceof Wizard && wizard.init) {
6767
// Ensure that init() was called. Needed because createWizardTester() does not call run().
68-
;(wizard as any)._ready = true
6968
await wizard.init()
70-
delete wizard.init
7169
}
7270

7371
const form = wizard instanceof Wizard ? wizard.boundForm : wizard

0 commit comments

Comments
 (0)