English | 中文
A VS Code extension that provides intelligent auto-completion for Lombok @ExtensionMethod static methods in Java files.
When you annotate a class with @ExtensionMethod and call a method on an expression, Lombok treats the first parameter of the utility method as the receiver — this extension makes those methods appear in the completion popup just like native methods.
Features
- Auto-completion — suggests
@ExtensionMethodstatic methods when typing.or.prefixon an expression - Type filtering — only compatible methods (matching the receiver's type) are suggested, with fallback to local variable declaration parsing when Hover Provider fails
- Prefix filtering — further narrows candidates as you type characters after the dot
- Snippet insertion — parameters are inserted with named placeholders (e.g.,
${1:int_maxWidth}), automatically omitting the receiver parameter - Generic type support — methods with type parameters like
<T>are properly parsed; generic parameters are treated as compatible with any type - Workspace and JAR sources — methods from both local source files and JAR dependencies are resolved
- Multi-stage source resolution — definition provider →
findFiles→ path derivation → same-directory search, with graceful fallback - Chained calls —
expr.method1(arg).method2().chains are fully supported; each step's type is resolved via JDT LS hover, with fallback to return-type inference from the cached method list - Live cache invalidation — when a workspace source file is saved, its cached methods are automatically cleared; TTL 10 minutes
Installation
Search for Lombok ExtMethod AutoComplete in the VS Code extension marketplace, or run:
ext install JensenQi.lombok-extmethod-autocomplete
Usage
- Add Lombok to your project (Maven/Gradle)
- Annotate a class with
@ExtensionMethod:
import lombok.experimental.ExtensionMethod;
import org.apache.commons.lang3.StringUtils;
@ExtensionMethod(StringUtils.class)
public class MyService {
public void process(String input) {
// Type "." or ".prefix" after the expression to see extension methods
input. ← shows abbreviate, capitalize, etc.
input.abbr ← shows abbreviate(int maxWidth), etc.
// Tab to insert snippet: methodName(argType_argName)
x.abbreviate(int_maxWidth)
}
}
Multiple extension classes are supported:
@ExtensionMethod({StringUtils.class, ObjectUtils.class, MyUtils.class})
How It Works
-
Annotation Parsing (
annotationResolver.ts) — scans the current document for@ExtensionMethodannotations using regex, resolves simple class names to FQN via imports and package declaration. Wildcard imports (import foo.*) cannot be resolved — use explicit imports for extension classes. -
Source Resolution (
jdtlsHelper.ts) — for each FQN, searches source in priority order:- Calls
vscode.executeDefinitionProviderto trigger JDT LS go-to-definition. The returned URI is either:- JAR class:
jdt://contents/...virtual file URI — opens decompiled source (FernFlower) viaopenTextDocument - Workspace class:
file://path/to/...— reads the source file directly
- JAR class:
- Falls back to
workspace.findFilesif the definition provider fails - Falls back to path derivation from the reference document's package path
- Finally tries the same directory as the reference document
- Calls
-
Method Parsing (
jdtlsHelper.ts) — extractspublic staticmethod signatures (name, parameter types, return type) from source using regex; parameter names are stripped; constructors and lambda methods are skipped. -
Type Filtering (
completionProvider.ts) — determines the receiver expression's type:- Prefers
vscode.executeHoverProviderto get the expression type - Falls back to
parseLocalVarType(regex-based local variable declaration parser) when Hover Provider fails - Only methods whose first parameter is compatible with the expression type are kept; generic type parameters (single letters like
T) are treated as compatible with any type - Also filters by characters typed after the dot (prefix filtering)
- Prefers
-
Completion — each method becomes a
CompletionItem(isIncomplete: trueto retrigger on each keystroke), label showsmethodName(args...), the first parameter (receiver) is dropped from the snippet since Lombok passes the target expression as the first argument automatically.
Module Structure
| Module | Responsibility |
|---|---|
extension.ts |
Entry point, registers CompletionProvider, commands, status bar |
completionProvider.ts |
Core completion logic: type filtering, prefix filtering, snippet generation |
annotationResolver.ts |
Parses @ExtensionMethod annotations and import statements |
jdtlsHelper.ts |
Source retrieval via JDT LS, static method signature parsing, file search fallback |
cache.ts |
Generic TTL cache for parsed method lists |
logger.ts |
Debug logging controlled by lombokExtensionMethod.debugEnabled |
Commands
These commands are only visible in the command palette when
lombokExtensionMethod.debugEnabledistrue.
| Command | Description |
|---|---|
Lombok EM: Resolve type at cursor |
Show which @ExtensionMethod classes are found |
Lombok EM: Clear method cache |
Clear the 10-minute method cache |
Lombok EM: Show parsed methods |
Print all parsed methods to the output channel |
Lombok EM: Show jdt.ls sortText |
Print jdt.ls completion sortText to the output channel |
Configuration
| Setting | Type | Default | Description |
|---|---|---|---|
lombokExtensionMethod.debugEnabled |
boolean | false |
Enable debug logging to "Lombok Extension Method" output channel |
Requirements
- VS Code 1.85+
- Extension Pack for Java (for JDT LS support)
- A project using Lombok with
@ExtensionMethod
Limitations
- Receiver type filtering relies on VS Code's Hover Provider. If neither hover nor local variable parsing can determine the type, all extension methods are shown (no filtering).
- Wildcard imports (
import some.package.*) are not supported for class resolution — use explicit imports for extension classes. - Complex generic bounds (
<T extends Comparable<T>>) may not parse correctly in method signatures.
Development
npm install
npm run compile
npx vitest run # run unit tests
npx vsce package # package .vsix
Launch the extension in VS Code by pressing F5 with the project open in a separate window.