example 7
Full Analysis of Merge Request gitlab-org/editor-extensions/gitlab-lsp!1323 (merged) and Related Work for Import-Based Code Suggestions Context
This report provides a comprehensive analysis of Merge Request gitlab-org/editor-extensions/gitlab-lsp!1323 and its closely related Merge Requests and issues. The central theme of this work is the enhancement of GitLab Duo Code Suggestions by incorporating "Imports Context" – context derived from files imported by the currently active document. This initiative aims to significantly improve the accuracy and relevance of AI-generated code suggestions.
Key Merge Request: gitlab-org/editor-extensions/gitlab-lsp!1323: chore: introduce JavascripttImportStore+
1. Overall Goal: Enhancing Code Suggestions with Import Context
The primary strategic goal behind this body of work is to improve the quality, accuracy, and relevance of GitLab Duo Code Suggestions. Current Code Suggestions primarily rely on the content of the open file and cursor position. This limited context often results in suggestions that lack awareness of related code, dependencies, and project structure, particularly in larger or more complex projects.
By analyzing import statements, the Language Server can identify and incorporate content from files that the current document explicitly depends on. This provides the AI model with a richer understanding of the surrounding codebase, leading to more intelligent and helpful suggestions. This initiative is a key part of broader efforts to advance context retrieval for AI tools within GitLab, as detailed in epics like:
- gitlab-org/editor-extensions&58: Imports Context Provider - (previously DaVinci phase 2)+
- gitlab-org&16331: Code Suggestions Additional Context Retrieval+
As stated in the description of epic gitlab-org/editor-extensions&58 (closed)+:
Code Suggestions currently uses open files and cursor context to show suggestions. Adding import statement analysis will provide better context about related files and dependencies.
Issue gitlab-org/gitlab#503839: Research: Additional contexts and Import context+ further elaborates on the collaboration and planning for how Imports Context will be implemented and consumed.
2. Architectural Overview of the Import Context System
The implementation of the Import Context feature involves several key components within the GitLab Language Server (gitlab-lsp):
-
ImportContextProvider: This is the central component responsible for orchestrating the gathering of import-based context. It identifies the active document's language, selects the appropriate resolver, and processes the resolved imports to generate context items. (Introduced in gitlab-org/editor-extensions/gitlab-lsp!1325: feat: introduce ImportContextProvider+, building on draft gitlab-org/editor-extensions/gitlab-lsp!1311 (closed)+, and detailed in issue gitlab-org/editor-extensions/gitlab-lsp#697: [LS] - ImportContextProvider+). -
AbstractImportHandler/AbstractImportResolver: This abstract class defines a standardized interface for language-specific import analysis. Concrete implementations parse code, identify import statements using Tree-sitter queries, extract metadata, and resolve import paths. (Introduced in gitlab-org/editor-extensions/gitlab-lsp!1321: chore: introduce AbstractImportHandler+). -
Language-Specific Resolvers: Concrete implementations of
AbstractImportHandlerfor specific languages. For example, theJavascriptImportResolver(orEcmascriptImportResolver) handles JavaScript, TypeScript, and Vue files. (Introduced in gitlab-org/editor-extensions/gitlab-lsp!1322: chore: introduce JavascriptImportResolver+). -
Import Stores: These components, like the
JavascriptImportStore, maintain an in-memory index of files within the workspace to enable fast lookups during import path resolution, significantly improving performance. (TheJavascriptImportStoreis introduced in the target MR, gitlab-org/editor-extensions/gitlab-lsp!1323 (merged)+). -
AIContextManager: The central orchestrator for discovering and utilizing various context providers, including theImportContextProvider. It manages the overall context gathering process. (Refactoring efforts like gitlab-org/editor-extensions/gitlab-lsp!1237: Draft: chore: expand AIContextManager to accept IDocContext+ aimed to enhance its capabilities, though this specific MR was closed). - Pre-processor Pipeline: A sequence of steps (filtering, ranking, content retrieval) applied to raw context items before they are sent to the Code Suggestions API. This ensures that the most relevant and permissible context is used. (Integration tests for filters in gitlab-org/editor-extensions/gitlab-lsp!1251: test: add integration tests for context filters+).
The architecture diagram from MR gitlab-org/editor-extensions/gitlab-lsp!1311 (closed)+ (Draft: feat: ImportContextProvider) illustrates this:
classDiagram
direction TB
class AIContextManager {
+getContext(IDocContext)
+getContextForCodeSuggestions(CodeSuggestionsAIRequest)
}
class DefaultImportContextProvider {
-logger: Logger
-fsClient: FsClient
-importHandlers: AbstractImportHandler[]
-projectAccessChecker: DuoProjectAccessChecker
-policy: FilePolicyProvider
-openTabsService: OpenTabsService
+getContextForCodeSuggestions(request: CodeSuggestionsAIRequest)
}
class AbstractImportHandler {
<<abstract>>
+getSupportedLanguages()* : TreeSitterLanguageName[]
+getTreeSitterQuery()* : Promise<string>
+getImportPathsToMetadata()* : Promise<Map>
+resolveImportPath()* : Promise<URI>
+enabledForLanguage(languageName) : boolean
}
class EcmascriptImportHandler {
-logger: Logger
-importStore: ECMAScriptImportStore
-fsClient: FsClient
+getSupportedLanguages()
+getTreeSitterQuery()
+getImportPathsToMetadata()
+resolveImportPath()
-getRequireImportPath()
-getAssociatedImportPath()
-getDynamicImportPath()
}
class ECMAScriptImportStore {
-filePathStore: Map
-repositoryService: RepositoryService
-configService: ConfigService
+getFile()
+storeReady()
-addFile()
-removeFile()
-setupFileSystemListener()
}
AIContextManager --> DefaultImportContextProvider : uses
DefaultImportContextProvider --> AbstractImportHandler : delegates to
AbstractImportHandler <|-- EcmascriptImportHandler : implements
EcmascriptImportHandler --> ECMAScriptImportStore : uses for lookup
3. Deep Dive into MR gitlab-org/editor-extensions/gitlab-lsp!1323: JavascriptImportStore
Merge Request gitlab-org/editor-extensions/gitlab-lsp!1323 (merged)+ introduces the JavascriptImportStore, a critical performance optimization for resolving ECMAScript (JavaScript, TypeScript, Vue) imports.
Purpose and Technical Contribution:
The primary goal of the JavascriptImportStore is to provide fast, in-memory lookups for files relevant to JavaScript-based import resolution. This minimizes filesystem overhead, which can be significant, especially in large projects.
As stated in the MR description:
This Merge Request introduces a new
JavascriptImportStorededicated to fast file lookups for Javascript-based import resolution. It maintains an in-memory mapping of recognized files (e.g.,.ts,.js,.vue) within a workspace folder so that import statements can be resolved with minimal filesystem overhead. This helps us better achieve our sub 50ms latency target.
Implementation Details:
-
DefaultJavascriptImportStoreClass:- Maintains a nested
Map(#filePathStore) where the outer key is the workspace folder URI and the inner map stores normalized file paths to their actual URIs. - Tracks files with specific extensions (e.g.,
.ts,.js,.vue) defined inTRACKED_EXTENSIONS. - Normalizes file paths by stripping common extensions to facilitate lookups (e.g.,
import './utils'can findutils.tsorutils.js). - Subscribes to
RepositoryServiceevents (onFileChange,onWorkspaceRepositoriesStart,onWorkspaceRepositoriesFinished) to keep its internal map synchronized with filesystem changes. - Provides a
findFilemethod for looking up file URIs based on potential import paths.
- Maintains a nested
-
Enhancements to
RepositoryandRepositoryService:-
Repositoryclass: AgetFilesmethod was added to retrieve files tracked by the repository, with options to exclude git-ignored or.gitfiles. -
RepositoryServiceclass: Enhanced to broadcast file system changes and repository lifecycle events (onFileChange,onWorkspaceRepositoriesStart,onWorkspaceRepositoriesFinished). This allows components likeJavascriptImportStoreto react to changes incrementally without rescanning the entire project.
The MR description further explains:
Additionally, this MR extends the
RepositoryandRepositoryServiceclasses to better-broadcast file changes to interested consumers like the newJavascriptImportStore. By exposinggetFiles()onRepositoryand emitting file updates viaonFileChange, downstream components can efficiently track newly created, changed, or deleted files without rescanning the entire project. -
Code Snippet: JavascriptImportStore Event Handling (Illustrative)
From src/common/ai_context_management/context_providers/imports/ast/javascript/javascript_import_store.ts in MR !1323:
#setupFileSystemListener() {
this.#repositoryService.onFileChange((event) => {
const fileUri = parseURIString(event.fileEvent.uri);
const { workspaceFolder } = event;
switch (event.fileEvent.type) {
case FileChangeType.Created:
case FileChangeType.Changed:
this.#addFile(fileUri, workspaceFolder);
break;
case FileChangeType.Deleted:
this.#removeFile(fileUri, workspaceFolder);
break;
default:
break;
}
});
// ... (handling for onWorkspaceRepositoriesStart and onWorkspaceRepositoriesFinished)
}
Performance Impact:
The JavascriptImportStore is crucial for meeting the strict performance targets (sub-50ms additional latency) for Code Suggestions. By caching file paths, it drastically reduces the time spent on filesystem I/O during import resolution.
Relation to ImportContextProvider:
The JavascriptImportStore is a dependency of the JavascriptImportResolver (or EcmascriptImportResolver), which in turn is used by the ImportContextProvider. The resolver queries the store to quickly find the URIs of imported modules.
Comments on MR !1323:
Review comments, such as those by elwyn-gitlab, focused on test coverage, path handling, and confirming the soundness of the in-memory map approach for performance.
-
elwyn-gitlab (2025-02-05T14:59:17Z):
Looks good overall! This is a great step towards getting the import context provider working performantly. I have a few minor comments and questions below.
-
elwyn-gitlab (2025-02-05T15:03:43Z): (Suggesting a test case for extension handling)
// For TypeScr... (truncated)Could we add a test for this case? E.g. adding a
.tsfile and then checking thatfindFileworks with and without the.tsextension. michaelangeloio (Author) (2025-02-05T15:06:56Z): Good idea, I'll add a test for this.
4. Closely Related Merge Requests and Their Contributions
The development of the Import Context feature is an "MR Train," with several MRs building upon each other:
-
gitlab-org/editor-extensions/gitlab-lsp!1321: chore: introduce AbstractImportHandler+
-
Contribution: Introduced the
AbstractImportHandler(laterAbstractImportResolver) class. This abstract class defines a standardized interface for language-specific import analysis, requiring implementations to provide Tree-sitter queries, extract metadata, and resolve import paths. It also introduced core types likeImportIdentifier,ImportMetadata, andResolvedImportMetadata. - Significance: Established the foundational abstraction for extensible, language-specific import processing.
-
Contribution: Introduced the
-
gitlab-org/editor-extensions/gitlab-lsp!1322: chore: introduce JavascriptImportResolver+
-
Contribution: Introduced the
EcmascriptImportResolver(orJavascriptImportResolver), a concrete implementation ofAbstractImportResolverfor JavaScript, TypeScript, TSX, and Vue files. It uses Tree-sitter queries to identify various import syntaxes (ESM, CommonJS, dynamic imports) and extracts import paths and identifiers. - Significance: Provided the first language-specific implementation for parsing ECMAScript imports, a core requirement for the feature.
-
Code Snippet: Tree-sitter Query from
query.ts(MR !1322)export const treeSitterQuery = `( [ ; 1. Named imports (with optional alias) (import_statement (import_clause (named_imports (import_specifier name: (identifier) @${captureMap.importedIdentifier} alias: (identifier)? @${captureMap.renamedIdentifier} ) ) ) source: (string) @${captureMap.importSource} ) // ... other import types (default, namespace, require, dynamic) ... ] )`;
-
Contribution: Introduced the
-
-
Contribution: Enhanced the
JavascriptImportResolverto correctly resolve relative import paths (e.g.,./file,../dir, directory imports resolving toindexfiles). It introducedresolveRelativeModulelogic. -
Significance: Made the resolver functional for a common and crucial type of import in JavaScript/TypeScript projects. It leverages the
JavascriptImportStorefor lookups.
-
Contribution: Enhanced the
-
gitlab-org/editor-extensions/gitlab-lsp!1311: Draft: feat: ImportContextProvider+ / gitlab-org/editor-extensions/gitlab-lsp!1325: feat: introduce ImportContextProvider+
-
Contribution: Introduced the
DefaultImportContextProviderclass. This class orchestrates the import analysis process by selecting the appropriate language handler (resolver), triggering AST parsing and import metadata extraction, resolving import paths, applying file policies, and creatingImportAIContextItems. -
Significance: This is the main service that ties together the resolvers and stores to provide import-based context to the
AIContextManager. -
Quote from MR !1325 Description:
This Merge Request debuts a brand-new
ImportContextProvider, allowing our AI features—particularly Code Suggestions—to leverage file-import analysis from ECMAScript, TypeScript, and other languages (via resolvers) in a standardized way.
-
Contribution: Introduced the
-
-
Contribution: Implemented the client-side logic for feature flagging Code Suggestions context providers. It updated
DuoFeatureAccessServiceto query a new GraphQL field (currentUser { codeSuggestionsContexts }) for enabled contexts.AIContextProviders can declare aduoRequiredFeature, andAIContextManagerfilters providers based on this. - Significance: Provided the mechanism to control the rollout of the Imports Context feature via a feature flag.
-
Contribution: Implemented the client-side logic for feature flagging Code Suggestions context providers. It updated
-
gitlab-org/gitlab!178402: Introduce codeSuggestionsContexts field to CurrentUser GraphQL type+
-
Contribution: Added the
codeSuggestionsContextsfield to theCurrentUserGraphQL type on the GitLab backend. This field returns a list of enabled context categories (e.g., "imports") based on feature flag checks (e.g.,code_suggestions_include_context_imports). -
Significance: Provided the server-side support for the client-side feature flagging mechanism implemented in
!1327.
-
Contribution: Added the
-
gitlab-org/editor-extensions/gitlab-lsp!1237: Draft: chore: expand AIContextManager to accept IDocContext+ (Closed Draft)
-
Contribution (Intended): Aimed to refactor
AIContextManagerand related components to acceptIDocContext, allowing providers to access current document information. - Significance: Showed the evolution towards more flexible context providers that are document-aware, a prerequisite for import analysis.
-
Contribution (Intended): Aimed to refactor
-
gitlab-org/editor-extensions/gitlab-lsp!1251: test: add integration tests for context filters+
- Contribution: Added comprehensive integration tests for advanced context filtering logic (byte size limits, project access, supported languages, empty content).
- Significance: Ensured the reliability of the context pipeline's filtering stage, which is crucial before and after refactoring context management.
5. Performance Considerations
Performance is a critical requirement for the Import Context feature, with a target of sub-50ms additional latency for Code Suggestions requests when imports context is enabled (gitlab-org/editor-extensions/gitlab-lsp#775: Imports Context - Initial Iteration - Rollout Plan+).
Key strategies and components addressing performance:
-
JavascriptImportStore(!1323): As detailed above, this in-memory store is the primary mechanism for fast file lookups, avoiding slow filesystem access. -
Analysis on
inlineCompletionRequest: The decision to perform import analysis during theinlineCompletionRequestrather than on every document change event helps avoid performance issues and race conditions from rapid typing (gitlab-org/editor-extensions/gitlab-lsp#697 (closed)+). - Tree-sitter: Leveraged for efficient AST parsing.
- Performance Investigations: Dedicated issues (gitlab-org/editor-extensions/gitlab-lsp#710 (closed)+, gitlab-org/editor-extensions/gitlab-lsp#788 (closed)+) track performance analysis and monitoring.
- Lazy Content Retrieval: Refactoring efforts (gitlab-org/editor-extensions/gitlab-lsp#834 (closed)+, gitlab-org/editor-extensions/gitlab-lsp#853 (closed)+) aim to fetch file content only when necessary.
6. Feature Flagging and Rollout Strategy
The Imports Context feature is rolled out using a feature flag to allow for controlled testing and gradual release.
-
Backend Feature Flag:
code_suggestions_include_context_importsis defined in the GitLab Rails application. -
GraphQL Exposure: MR gitlab-org/gitlab!178402 (merged)+ exposes the status of this flag (and others) via the
currentUser { codeSuggestionsContexts }GraphQL field. -
Client-Side Check: MR gitlab-org/editor-extensions/gitlab-lsp!1327 (merged)+ updates the
DuoFeatureAccessServicein the LSP to query this GraphQL field. TheAIContextManagerthen uses this service to determine if theImportContextProvidershould be active. - Rollout Plan: Issue gitlab-org/editor-extensions/gitlab-lsp#775+ outlines the rollout strategy, success criteria (quality improvement, latency targets), and feedback collection.
This multi-layered approach ensures that the feature can be enabled or disabled at the user level, managed from the backend.
7. Integration into the Code Suggestions Context Pipeline
The Imports Context is integrated into the existing Code Suggestions context pipeline as follows:
- The
AIContextManagerqueries all registered context providers. - If the
ImportContextProvideris enabled (via feature flag check in!1327), it analyzes the current document's imports using its resolver (e.g.,JavascriptImportResolverfrom!1322,!1324) and theJavascriptImportStore(!1323). - The
ImportContextProviderreturnsAIContextItems representing the resolved imported files. - These items, along with context from other providers (e.g., Open Tabs), are passed to a pre-processor pipeline.
- The pipeline filters items (tested in
!1251), ranks them using aContextRanker(gitlab-org/editor-extensions/gitlab-lsp#698 (closed)+), and retrieves content for the top-ranked items. - The final, processed context is included in the payload sent to the Code Suggestions API.
8. Conclusion
Merge Request gitlab-org/editor-extensions/gitlab-lsp!1323 is a pivotal piece in a larger, coordinated effort to enhance GitLab Duo Code Suggestions by incorporating context from imported files. The JavascriptImportStore it introduces is a critical performance optimization, enabling fast resolution of ECMAScript imports. This store is a foundational component for the ImportContextProvider and its associated language-specific resolvers.
The related MRs and issues demonstrate a comprehensive approach, covering:
-
Architectural Design: Abstracting language-specific logic (
!1321), implementing concrete resolvers (!1322,!1324), and orchestrating context gathering (!1311,!1325). -
Performance: Prioritizing low latency through in-memory stores and optimized analysis strategies (#710,
!1323). -
Feature Control: Implementing robust feature flagging on both backend (
gitlab!178402) and client (!1327) for controlled rollout (#726). - Pipeline Integration: Ensuring the new context source fits seamlessly into the existing context processing pipeline, including filtering and ranking.
This body of work represents a significant advancement in providing richer, more relevant context to AI models, with the ultimate aim of delivering more accurate and helpful Code Suggestions to GitLab users. MR !1323 plays a vital role by ensuring that this enhanced context can be gathered efficiently.