-
Notifications
You must be signed in to change notification settings - Fork 158
feat: context provider api support for java #1489
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+568
−2
Merged
Changes from 4 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
86c38e4
feat: context provider api support for java
wenytang-ms 0d78220
feat: register registerCopilotContextProviders
wenytang-ms 1896f00
feat: register registerCopilotContextProviders
wenytang-ms 1d257e9
feat: update
wenytang-ms 42a47ce
fix: update code according to the comments
wenytang-ms d982414
fix: update the docu hash logic
wenytang-ms c88b1fb
fix: update code
wenytang-ms 465260a
fix: update the code logic according to comments
wenytang-ms 363c754
fix: update code according to comments
wenytang-ms d730437
feat: remove cache design
wenytang-ms 1ba9788
feat: add telemetry data report
wenytang-ms ada5f17
feat: remove get java version
wenytang-ms 718abf5
fix: update
wenytang-ms File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,211 @@ | ||
| /*--------------------------------------------------------------------------------------------- | ||
| * Copyright (c) Microsoft Corporation. All rights reserved. | ||
| * Licensed under the MIT License. See License.txt in the project root for license information. | ||
| *--------------------------------------------------------------------------------------------*/ | ||
| import * as vscode from 'vscode'; | ||
| import * as crypto from 'crypto'; | ||
| import { INodeImportClass } from './copilotHelper'; | ||
|
|
||
| /** | ||
| * Cache entry interface for storing import data with timestamp | ||
| */ | ||
| interface CacheEntry { | ||
| value: INodeImportClass[]; | ||
| timestamp: number; | ||
| } | ||
|
|
||
| /** | ||
| * Configuration options for the context cache | ||
| */ | ||
| interface ContextCacheOptions { | ||
| /** Cache expiry time in milliseconds. Default: 5 minutes */ | ||
| expiryTime?: number; | ||
| /** Enable automatic cleanup interval. Default: true */ | ||
| enableAutoCleanup?: boolean; | ||
| /** Enable file watching for cache invalidation. Default: true */ | ||
| enableFileWatching?: boolean; | ||
| } | ||
|
|
||
| /** | ||
| * Context cache manager for storing and managing Java import contexts | ||
| */ | ||
| export class ContextCache { | ||
| private readonly cache = new Map<string, CacheEntry>(); | ||
| private readonly expiryTime: number; | ||
| private readonly enableAutoCleanup: boolean; | ||
| private readonly enableFileWatching: boolean; | ||
|
|
||
| private cleanupInterval?: NodeJS.Timeout; | ||
| private fileWatcher?: vscode.FileSystemWatcher; | ||
|
|
||
| constructor(options: ContextCacheOptions = {}) { | ||
| this.expiryTime = options.expiryTime ?? 5 * 60 * 1000; // 5 minutes default | ||
| this.enableAutoCleanup = options.enableAutoCleanup ?? true; | ||
| this.enableFileWatching = options.enableFileWatching ?? true; | ||
| } | ||
|
|
||
| /** | ||
| * Initialize the cache with VS Code extension context | ||
| * @param context VS Code extension context for managing disposables | ||
| */ | ||
| public initialize(context: vscode.ExtensionContext): void { | ||
| if (this.enableAutoCleanup) { | ||
| this.startPeriodicCleanup(); | ||
| } | ||
|
|
||
| if (this.enableFileWatching) { | ||
| this.setupFileWatcher(); | ||
| } | ||
|
|
||
| // Register cleanup on extension disposal | ||
| context.subscriptions.push( | ||
| new vscode.Disposable(() => { | ||
| this.dispose(); | ||
| }) | ||
| ); | ||
|
|
||
| if (this.fileWatcher) { | ||
| context.subscriptions.push(this.fileWatcher); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Generate a hash for the document URI to use as cache key | ||
| * @param uri Document URI | ||
| * @returns Hashed URI string | ||
| */ | ||
| private generateCacheKey(uri: vscode.Uri): string { | ||
| return crypto.createHash('md5').update(uri.toString()).digest('hex'); | ||
| } | ||
|
|
||
| /** | ||
| * Get cached imports for a document URI | ||
| * @param uri Document URI | ||
| * @returns Cached imports or null if not found/expired | ||
| */ | ||
| public get(uri: vscode.Uri): INodeImportClass[] | null { | ||
| const key = this.generateCacheKey(uri); | ||
| const cached = this.cache.get(key); | ||
|
|
||
| if (!cached) { | ||
| return null; | ||
| } | ||
|
|
||
| // Check if cache is expired | ||
| if (this.isExpired(cached)) { | ||
| this.cache.delete(key); | ||
| return null; | ||
| } | ||
|
|
||
| return cached.value; | ||
| } | ||
|
|
||
| /** | ||
| * Set cached imports for a document URI | ||
| * @param uri Document URI | ||
| * @param imports Import class array to cache | ||
| */ | ||
| public set(uri: vscode.Uri, imports: INodeImportClass[]): void { | ||
| const key = this.generateCacheKey(uri); | ||
| this.cache.set(key, { | ||
| value: imports, | ||
| timestamp: Date.now() | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Check if a cache entry is expired | ||
| * @param entry Cache entry to check | ||
| * @returns True if expired, false otherwise | ||
| */ | ||
| private isExpired(entry: CacheEntry): boolean { | ||
| return Date.now() - entry.timestamp > this.expiryTime; | ||
| } | ||
|
|
||
| /** | ||
| * Clear expired cache entries | ||
| */ | ||
| public clearExpired(): void { | ||
| const now = Date.now(); | ||
| for (const [key, entry] of this.cache.entries()) { | ||
| if (now - entry.timestamp > this.expiryTime) { | ||
| this.cache.delete(key); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Clear all cache entries | ||
| */ | ||
| public clear(): void { | ||
| this.cache.clear(); | ||
| } | ||
|
|
||
| /** | ||
| * Invalidate cache for specific URI | ||
| * @param uri URI to invalidate | ||
| */ | ||
| public invalidate(uri: vscode.Uri): void { | ||
| const key = this.generateCacheKey(uri); | ||
| if (this.cache.has(key)) { | ||
| this.cache.delete(key); | ||
| console.log('Cache invalidated for:', uri.toString()); | ||
wenytang-ms marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Get cache statistics | ||
| * @returns Object containing cache size and other statistics | ||
| */ | ||
| public getStats(): { size: number; expiryTime: number } { | ||
| return { | ||
| size: this.cache.size, | ||
| expiryTime: this.expiryTime | ||
| }; | ||
| } | ||
|
|
||
| /** | ||
| * Start periodic cleanup of expired cache entries | ||
| */ | ||
| private startPeriodicCleanup(): void { | ||
| this.cleanupInterval = setInterval(() => { | ||
| this.clearExpired(); | ||
| }, this.expiryTime); | ||
| } | ||
|
|
||
| /** | ||
| * Setup file system watcher for Java files to invalidate cache on changes | ||
| */ | ||
| private setupFileWatcher(): void { | ||
| this.fileWatcher = vscode.workspace.createFileSystemWatcher('**/*.java'); | ||
wenytang-ms marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| const invalidateHandler = (uri: vscode.Uri) => { | ||
| this.invalidate(uri); | ||
| }; | ||
|
|
||
| this.fileWatcher.onDidChange(invalidateHandler); | ||
| this.fileWatcher.onDidDelete(invalidateHandler); | ||
| } | ||
|
|
||
| /** | ||
| * Dispose of all resources (intervals, watchers, etc.) | ||
| */ | ||
| public dispose(): void { | ||
| if (this.cleanupInterval) { | ||
| clearInterval(this.cleanupInterval); | ||
| this.cleanupInterval = undefined; | ||
| } | ||
|
|
||
| if (this.fileWatcher) { | ||
| this.fileWatcher.dispose(); | ||
| this.fileWatcher = undefined; | ||
| } | ||
|
|
||
| this.clear(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Default context cache instance | ||
| */ | ||
| export const contextCache = new ContextCache(); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT license. | ||
|
|
||
| import { commands, Uri } from "vscode"; | ||
| import { logger } from "../utils"; | ||
|
|
||
| export interface INodeImportClass { | ||
| uri: string; | ||
| className: string; // Changed from 'class' to 'className' to match Java code | ||
| } | ||
| /** | ||
| * Helper class for Copilot integration to analyze Java project dependencies | ||
| */ | ||
| export namespace CopilotHelper { | ||
| /** | ||
| * Resolves all local project types imported by the given file | ||
| * @param fileUri The URI of the Java file to analyze | ||
| * @returns Array of strings in format "type:fully.qualified.name" where type is class|interface|enum|annotation | ||
| */ | ||
| export async function resolveLocalImports(fileUri: Uri): Promise<INodeImportClass[]> { | ||
| try { | ||
wenytang-ms marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return await commands.executeCommand("java.execute.workspaceCommand", "java.project.getImportClassContent", fileUri) || []; | ||
| } catch (error) { | ||
| logger.error("Error resolving copilot request:", error); | ||
wenytang-ms marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return []; | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.