Skip to content

Commit 9476765

Browse files
committed
refactored filePath to getter functions
1 parent dabf670 commit 9476765

File tree

4 files changed

+50
-74
lines changed

4 files changed

+50
-74
lines changed

packages/core/src/codewhisperer/nextEditPrediction/PredictionTracker.ts

Lines changed: 43 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,15 @@ import * as diffGenerator from './diffContextGenerator'
1111
import * as codewhispererClient from '../client/codewhisperer'
1212
import { predictionTrackerDefaultConfig } from '../models/constants'
1313

14+
const snapshotDirName = 'AmazonQ-file-snapshots'
15+
const snapshotFileSuffix = '.nep-snapshot'
16+
17+
// defaul values are stored in codewhisperer/model/constants
1418
export interface FileTrackerConfig {
15-
/** Maximum number of files to track (default: 15) */
1619
maxFiles: number
17-
/** Maximum total size of all snapshots in kilobytes (default: 200) */
1820
maxStorageSizeKb: number
19-
/** Debounce interval in milliseconds (default: 2000) */
2021
debounceIntervalMs: number
21-
/** Maximum age of snapshots in milliseconds (default: 30000) */
2222
maxAgeMs: number
23-
/** Maximum number of supplemental contexts to return (default: 15) */
2423
maxSupplementalContext: number
2524
}
2625

@@ -38,16 +37,15 @@ export class PredictionTracker {
3837
private snapshots: Map<string, FileSnapshot[]> = new Map()
3938
readonly config: FileTrackerConfig
4039
private storageSize: number = 0
41-
private storagePath?: string
40+
private storagePath: string
4241

4342
constructor(extensionContext: vscode.ExtensionContext, config?: Partial<FileTrackerConfig>) {
4443
this.config = {
4544
...predictionTrackerDefaultConfig,
4645
...config,
4746
}
4847

49-
// Use workspace storage
50-
this.storagePath = extensionContext.storageUri?.fsPath
48+
this.storagePath = extensionContext.storageUri?.fsPath as string
5149

5250
void this.ensureStorageDirectoryExists()
5351
void this.loadSnapshotsFromStorage()
@@ -211,10 +209,6 @@ export class PredictionTracker {
211209
return Array.from(this.snapshots.keys())
212210
}
213211

214-
/**
215-
* Gets the total number of snapshots across all files
216-
* @returns Total snapshot count
217-
*/
218212
public getTotalSnapshotCount(): number {
219213
let count = 0
220214
for (const snapshots of this.snapshots.values()) {
@@ -223,42 +217,51 @@ export class PredictionTracker {
223217
return count
224218
}
225219

220+
private getSnapshotsDirectoryPath(): string {
221+
return path.join(this.storagePath, snapshotDirName)
222+
}
223+
224+
private getSnapshotFilePath(storageKey: string): string {
225+
const snapshotsDir = this.getSnapshotsDirectoryPath()
226+
return path.join(snapshotsDir, `${storageKey}${snapshotFileSuffix}`)
227+
}
228+
226229
/**
227230
* Saves snapshot content to Storage
228231
* @param storageKey The storage key for the snapshot
229232
* @param content The content to save
230233
*/
231234
private async saveSnapshotContentToStorage(storageKey: string, content: string): Promise<void> {
232-
if (!this.storagePath) {
233-
throw new Error('Storage path not available')
234-
}
235+
const snapshotsDir = this.getSnapshotsDirectoryPath()
235236

236-
const snapshotsDir = path.join(this.storagePath, 'AmazonQ-file-snapshots')
237237
if (!(await fs.existsDir(snapshotsDir))) {
238238
await fs.mkdir(snapshotsDir)
239239
}
240240

241-
const filePath = path.join(snapshotsDir, `${storageKey}.nep-snapshot`)
242-
await fs.writeFile(filePath, content)
241+
const filePath = this.getSnapshotFilePath(storageKey)
242+
if (!filePath) {
243+
throw new Error('Failed to create snapshot file path')
244+
}
245+
246+
try {
247+
await fs.writeFile(filePath, content)
248+
} catch (err) {
249+
getLogger().error(`Failed to write snapshot to Storage: ${err}`)
250+
}
243251
}
244252

245253
private async deleteSnapshot(snapshot: FileSnapshot): Promise<void> {
246254
if (!this.storagePath) {
247255
return
248256
}
249257

250-
// Update the storage size
251258
this.storageSize -= snapshot.size
259+
const filePath = this.getSnapshotFilePath(snapshot.storageKey)
252260

253-
const snapshotsDir = path.join(this.storagePath, 'AmazonQ-file-snapshots')
254-
const filePath = path.join(snapshotsDir, `${snapshot.storageKey}.nep-snapshot`)
255-
256-
if (await fs.exists(filePath)) {
257-
try {
258-
await fs.delete(filePath)
259-
} catch (err) {
260-
getLogger().error(`Failed to delete snapshot from Storage: ${err}`)
261-
}
261+
try {
262+
await fs.delete(filePath)
263+
} catch (err) {
264+
getLogger().error(`Failed to delete snapshot from Storage: ${err}`)
262265
}
263266
}
264267

@@ -268,17 +271,11 @@ export class PredictionTracker {
268271
* @returns The string content of the snapshot
269272
*/
270273
public async getSnapshotContent(snapshot: FileSnapshot): Promise<string> {
271-
if (!this.storagePath) {
272-
throw new Error('Storage path not available')
273-
}
274-
275-
const snapshotsDir = path.join(this.storagePath, 'AmazonQ-file-snapshots')
276-
const filePath = path.join(snapshotsDir, `${snapshot.storageKey}.nep-snapshot`)
274+
const filePath = this.getSnapshotFilePath(snapshot.storageKey)
277275

278276
try {
279277
return await fs.readFileText(filePath)
280278
} catch (err) {
281-
getLogger().error(`Failed to read snapshot content from Storage: ${err}`)
282279
throw new Error(`Failed to read snapshot content: ${err}`)
283280
}
284281
}
@@ -307,16 +304,12 @@ export class PredictionTracker {
307304
// Load all snapshot contents
308305
const snapshotContents: diffGenerator.SnapshotContent[] = []
309306
for (const snapshot of snapshots) {
310-
try {
311-
const content = await this.getSnapshotContent(snapshot)
312-
snapshotContents.push({
313-
filePath: snapshot.filePath,
314-
content,
315-
timestamp: snapshot.timestamp,
316-
})
317-
} catch (err) {
318-
getLogger().error(`Failed to load snapshot content: ${err}`)
319-
}
307+
const content = await this.getSnapshotContent(snapshot)
308+
snapshotContents.push({
309+
filePath: snapshot.filePath,
310+
content,
311+
timestamp: snapshot.timestamp,
312+
})
320313
}
321314

322315
// Use the diffGenerator module to generate supplemental contexts
@@ -329,22 +322,15 @@ export class PredictionTracker {
329322
}
330323

331324
private async ensureStorageDirectoryExists(): Promise<void> {
332-
if (!this.storagePath) {
333-
return
334-
}
325+
const snapshotsDir = this.getSnapshotsDirectoryPath()
335326

336-
const snapshotsDir = path.join(this.storagePath, 'AmazonQ-file-snapshots')
337327
if (!(await fs.existsDir(snapshotsDir))) {
338328
await fs.mkdir(snapshotsDir)
339329
}
340330
}
341331

342332
private async loadSnapshotsFromStorage(): Promise<void> {
343-
if (!this.storagePath) {
344-
return
345-
}
346-
347-
const snapshotsDir = path.join(this.storagePath, 'AmazonQ-file-snapshots')
333+
const snapshotsDir = this.getSnapshotsDirectoryPath()
348334
if (!(await fs.existsDir(snapshotsDir))) {
349335
return
350336
}
@@ -355,11 +341,11 @@ export class PredictionTracker {
355341

356342
// First, collect all the metadata files
357343
for (const [filename, fileType] of files) {
358-
if (!filename.endsWith('.nep-snapshot') || fileType !== vscode.FileType.File) {
344+
if (!filename.endsWith(snapshotFileSuffix) || fileType !== vscode.FileType.File) {
359345
continue
360346
}
361347

362-
const storageKey = filename.substring(0, filename.length - '.nep-snapshot'.length)
348+
const storageKey = filename.substring(0, filename.length - snapshotFileSuffix.length)
363349
const parts = storageKey.split('-')
364350
const timestamp = parseInt(parts[parts.length - 1], 10)
365351
const originalFilename = parts.slice(0, parts.length - 1).join('-')
@@ -373,7 +359,7 @@ export class PredictionTracker {
373359

374360
// Now process each file that we found
375361
for (const [storageKey, metadata] of metadataFiles.entries()) {
376-
const contentPath = path.join(snapshotsDir, `${storageKey}.nep-snapshot`)
362+
const contentPath = this.getSnapshotFilePath(storageKey)
377363

378364
try {
379365
// if original file no longer exists, delete the snapshot

packages/core/src/codewhisperer/nextEditPrediction/activation.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ import { ExtContext } from '../../shared/extensions'
1212
export let predictionTracker: PredictionTracker | undefined
1313
let keyStrokeHandler: PredictionKeyStrokeHandler | undefined
1414

15-
/**
16-
* Activates the Next Edit Prediction system
17-
*/
1815
export function activateNextEditPrediction(context: ExtContext): void {
16+
// Skip activation if storage path is not available
17+
if (!context.extensionContext.storageUri?.fsPath) {
18+
getLogger().info('Next Edit Prediction not activated: storage path is not available')
19+
return
20+
}
21+
1922
// Initialize the tracker
2023
predictionTracker = new PredictionTracker(context.extensionContext)
2124

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export async function fetchSupplementalContextForTest(
102102
async function generateSupplementalContextFromFocalFile(
103103
filePath: string,
104104
strategy: UtgStrategy,
105-
cancellationToken?: vscode.CancellationToken
105+
cancellationToken: vscode.CancellationToken
106106
): Promise<CodeWhispererSupplementalContextItem[]> {
107107
const fileContent = await fs.readFileText(vscode.Uri.parse(filePath!).fsPath)
108108

packages/core/src/test/codewhisperer/nextEditPrediction/PredictionTracker.test.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -198,19 +198,6 @@ describe('PredictionTracker', function () {
198198
assert.ok(readFileTextStub.calledWith(snapshotPath))
199199
})
200200

201-
it('should throw error if storage path not available', async function () {
202-
// Clear the storage path
203-
const trackerWithoutStorage = new PredictionTracker({ ...mockExtensionContext, storageUri: undefined })
204-
205-
try {
206-
await trackerWithoutStorage.getSnapshotContent(snapshot)
207-
assert.fail('Should have thrown an error')
208-
} catch (err) {
209-
assert.ok(err instanceof Error)
210-
assert.strictEqual((err as Error).message, 'Storage path not available')
211-
}
212-
})
213-
214201
it('should throw error if read fails', async function () {
215202
// Set up readFileText to throw
216203
readFileTextStub.rejects(new Error('Read error'))

0 commit comments

Comments
 (0)