Skip to content

Use SearchEngine.getSearchParticipants() for non-Java language search#3732

Closed
arcivanov wants to merge 1 commit into
eclipse-jdtls:mainfrom
arcivanov:feature/search-participant-extension-point
Closed

Use SearchEngine.getSearchParticipants() for non-Java language search#3732
arcivanov wants to merge 1 commit into
eclipse-jdtls:mainfrom
arcivanov:feature/search-participant-extension-point

Conversation

@arcivanov
Copy link
Copy Markdown

@arcivanov arcivanov commented Mar 8, 2026

Summary

  • Update all search call sites (ReferencesHandler, CodeLensHandler, ImplementationCollector, HoverInfoProvider, WorkspaceSymbolHandler) to use SearchEngine.getSearchParticipants() instead of hardcoding only the default Java participant
  • Supplement WorkspaceSymbolHandler.searchAllTypeNames() and searchAllMethodNames() with search() calls through contributed participants — both APIs only query the default Java participant's indexes, making non-Java types and methods invisible to workspace/symbol queries
  • Add fallback in JDTUtils.resolveCompilationUnit(IFile) to query contributed DerivedSourceSearchParticipant.getCompilationUnit(IFile) for non-Java source files
  • Add fallback in JDTUtils.findElementsAtSelection() to search contributed participants when Java's codeSelect() returns empty — enables go-to-definition and hover for types/methods provided by non-Java languages (e.g., Kotlin facade classes and property accessors) from Java source files
  • Add type hierarchy support for contributed participants: supertype resolution via search, subtype supplementation from contributed participants, and fallback element re-resolution when JDT cannot reconstitute the element from its handle identifier
  • Accept inaccurate search matches in ReferencesHandler when the search target itself is a non-Java element (contributed participants may not provide full accuracy information)
  • Resolve correct LSP language ID for hover MarkedStrings via DerivedSourceSearchParticipantRegistry instead of hardcoding "java"
  • Guard NavigateToDefinitionHandler.computeBreakContinue() with isJavaLikeFileName to prevent ClassCastException when ECJ's ASTParser attempts to parse a contributed ICompilationUnit (e.g., Kotlin)
  • Log unhandled exceptions in BaseJDTLanguageServer.computeAsync() and JDTLanguageServer.computeAsyncWithClientProgress() instead of silently swallowing them

Motivation

SearchEngine.search() already supports multiple SearchParticipant instances, but all call sites in jdtls hardcode a single-element array containing only the default Java participant. This prevents non-Java languages from contributing search results for cross-language features.

With the new org.eclipse.jdt.core.derivedSourceSearchParticipant extension point (eclipse-jdt/eclipse.jdt.core#4938), languages like Kotlin can register search participants that index .kt files and contribute to JDT's search infrastructure. This PR wires jdtls to use those contributed participants.

Changes

1. Search call sites → getSearchParticipants()

ReferencesHandler, CodeLensHandler, ImplementationCollector, and HoverInfoProvider.isResolved() now call SearchEngine.getSearchParticipants() which returns [default, ...contributed].

2. WorkspaceSymbolHandler — contributed participant supplementation

searchAllTypeNames() and searchAllMethodNames() only query indexes through the default Java search participant (see BasicSearchEngine line 1987: getDefaultSearchParticipant(), // Java search only). Non-Java types and methods indexed by contributed participants are invisible to these APIs.

After both the existing searchAllTypeNames and searchAllMethodNames calls, supplementary search() calls are now run through contributed participants only (excluding the default). They create TYPE/METHOD DECLARATIONS patterns with the same match rule (camelcase or wildcard) used by the workspace symbol query, and convert SearchMatch results to SymbolInformation with proper location, container name, and symbol kind.

3. ReferencesHandler — accept inaccurate matches for non-Java elements

When the search target is a non-Java element (resolved via a contributed participant), ReferencesHandler now accepts inaccurate search matches. Contributed participants may not provide full accuracy information, and filtering these out would silently drop valid cross-language references.

4. resolveCompilationUnit(IFile) fallback

When a non-Java file (e.g., .kt) is opened, the method now queries contributed participants via DerivedSourceSearchParticipant.getCompilationUnit(IFile) as a fallback after the standard Java resolution path. This enables document symbols, hover, go-to-definition, call hierarchy, and code lenses for derived source languages.

5. findElementsAtSelection() search participant fallback

When Java's codeSelect() returns empty (which happens for types and methods provided by non-Java languages), a new resolveViaSearchParticipants() helper extracts the identifier at the cursor and searches contributed participants for matching TYPE or METHOD declarations. This fixes Java→Kotlin navigation gaps (go-to-definition and hover on Kotlin facade classes and property accessors from Java files).

6. Type hierarchy support for contributed participants

  • Fallback element resolution: When TypeHierarchyHandler cannot reconstitute a IJavaElement from its handle identifier (which happens for contributed elements), it falls back to codeSelect() at the element's source position to re-resolve it
  • Contributed supertype resolution (resolveContributedSupertypes): For non-Java types, JDT's newSupertypeHierarchy() does not work. Instead, the superclass and superinterface names are resolved via SearchEngine search across all participants, building the hierarchy items from the resolved IType instances
  • Contributed subtype supplementation (supplementWithContributedSubtypes): After JDT computes subtypes via its own hierarchy, a secondary IMPLEMENTORS search is run against contributed participants only (excluding the default Java participant) to discover additional subtypes from non-Java languages

7. Correct language ID for hover MarkedStrings

HoverInfoProvider.getLanguageId() queries DerivedSourceSearchParticipantRegistry for the file extension and its associated LSP language ID, falling back to "java" for standard Java elements. This ensures hover popups render syntax highlighting for the correct language.

8. NavigateToDefinitionHandler — guard ECJ AST parsing for non-Java files

computeBreakContinue() uses ASTParser.createAST() to parse break/continue statements, which internally casts the ICompilationUnit to ECJ's org.eclipse.jdt.internal.compiler.env.ICompilationUnit. Contributed compilation units (e.g., KotlinCompilationUnit) do not implement this internal interface, causing a ClassCastException. Added JavaCore.isJavaLikeFileName() guard to skip break/continue resolution for non-Java files.

9. Log unhandled exceptions in computeAsync()

BaseJDTLanguageServer.computeAsync() and JDTLanguageServer.computeAsyncWithClientProgress() now attach a whenComplete() handler that logs unhandled exceptions instead of silently swallowing them. This makes failures in LSP request handlers visible in the server log for diagnosis.

Backward Compatibility

When no search participant extensions are registered, getSearchParticipants() returns only the default Java participant, and the fallback paths only run when standard JDT resolution already returned empty. Behavior is identical to before.

Test plan

  • Existing DerivedSourceSearchParticipantsTest (14 tests) passes
  • Cross-language workspace/symbol: Kotlin types found via camelcase, wildcard, and exact match queries
  • Cross-language hover: Kotlin→Java type references resolve with full Javadoc
  • Cross-language go-to-definition: Kotlin→Java and Java→Kotlin navigation
  • Cross-language find-references: includes both Java and Kotlin files
  • Java→Kotlin facade class navigation (e.g., NumberExtensionsKt)
  • Java→Kotlin property accessor navigation (e.g., getBIG_DECIMAL_HUNDRED)
  • Type hierarchy: supertypes and subtypes resolve across Java/Kotlin boundary

@eclipse-ls-bot
Copy link
Copy Markdown
Contributor

Can one of the admins verify this patch?

@arcivanov arcivanov force-pushed the feature/search-participant-extension-point branch 3 times, most recently from 1803d94 to 2af1816 Compare March 9, 2026 00:39
@fbricon
Copy link
Copy Markdown
Contributor

fbricon commented Mar 9, 2026

add to whitelist

@fbricon
Copy link
Copy Markdown
Contributor

fbricon commented Mar 9, 2026

Thanks for the contribution @arcivanov. I'm not too familiar with JDT's Index API and I have a bunch of questions:

  • instead of creating a new JDT.LS extension point, couldn't we reuse an existing JDT Core one?
  • your implementation doesn't take care of indexing, even though the search participants are supposed to implement a bunch of index* methods. Who's responsible for triggering indexing then?
  • can you share what concrete implementation will be contributed via this extension point? Do you have a working kotlin plugin?

@fbricon
Copy link
Copy Markdown
Contributor

fbricon commented Mar 9, 2026

@jjohnstn could you please take a look?

@jjohnstn
Copy link
Copy Markdown
Contributor

jjohnstn commented Mar 9, 2026

@jjohnstn could you please take a look?

Will do.

@jjohnstn
Copy link
Copy Markdown
Contributor

@fbricon Regarding JDT extensions, there is an existing extension in JDT, but it is in JDT UI and not accessible to jdt.ls.

@arcivanov
Copy link
Copy Markdown
Author

So, @fbricon you're quite right, this only covered the read path, not the indexing one. This PR will be transformed (it's still needed even further trimmed down) but the extension point is moving to JDT Core proper.

Additionally I'm finishing up a functional prototype of how this PR and JDT Core PR (incoming) will work together to facilitate hybrid language project LSPs for Java ecosystem.

@arcivanov arcivanov force-pushed the feature/search-participant-extension-point branch from 2af1816 to 45c547c Compare March 16, 2026 17:55
@arcivanov arcivanov changed the title Add searchParticipant extension point for non-Java language integration Use SearchEngine.getSearchParticipants() for non-Java language search Mar 16, 2026
@arcivanov
Copy link
Copy Markdown
Author

An integration demo (that is stubbed out but won't be for long is available here): https://github.com/karellen/karellen-jdtls-kotlin

@arcivanov
Copy link
Copy Markdown
Author

An integration demo (that is stubbed out but won't be for long is available here): https://github.com/karellen/karellen-jdtls-kotlin

@fbricon you requested a use prototype

@fbricon
Copy link
Copy Markdown
Contributor

fbricon commented Mar 18, 2026

@arcivanov your readme mentions using kt as an isJavaDerivedFileName match, beware, that will introduce JDT compilation errors in kt files, as JDT will consider they're valid java content. See #3666 (comment)

@arcivanov
Copy link
Copy Markdown
Author

@fbricon thank you noted I'll investigate it and get back to you. There is another patch that will be required into the "manipulation" to get call-hierarchy to support inter-language references as well.

@arcivanov
Copy link
Copy Markdown
Author

arcivanov commented Mar 20, 2026

@arcivanov your readme mentions using kt as an isJavaDerivedFileName match, beware, that will introduce JDT compilation errors in kt files

@fbricon I don't think so. As I see it right now (as far as I progressed in the prototype) the builder exclusively uses isJavaLikeFileName (which checks javaSource content type only), never isJavaDerivedFileName. So .kt files registered under javaDerivedSource will not be compiled.

The areas where isJavaDerivedFileName is used:

  • PackageFragment.getCompilationUnit() — allows creating a CompilationUnit handle for .kt files (needed for search/navigation)
  • SourceMapper — allows mapping source in jars containing .kt files
  • DeltaProcessor — triggers indexing (not compilation) for derived source files
  • IndexAllProject / AddFolderToIndex — index discovery

None of these trigger ECJ compilation. Your concern is based on the javaSource content type behavior you observed in PR #3666, but javaDerivedSource is specifically designed to avoid that problem.

Does it make sense or I'm missing something?

arcivanov added a commit to arcivanov/eclipse.jdt.ui that referenced this pull request Mar 21, 2026
Incoming calls (CallerMethodWrapper):

Replace hardcoded `new SearchParticipant[] { getDefaultSearchParticipant() }`
with `SearchEngine.getSearchParticipants()` so that incoming call searches
include results from contributed search participants registered via the
`org.eclipse.jdt.core.searchParticipant` extension point.

Outgoing calls (CalleeMethodWrapper):

When the member has no Java AST (i.e. `getCompilationUnitNode()` returns
null), fall back to `SearchParticipant.locateCallees()` on all contributed
participants. Each participant can report call sites within the member's
body. Returned callees are resolved to full declarations via
`resolveCallee()`, which handles METHOD, FIELD, and TYPE element types.

Non-standard ICompilationUnit handling (CallHierarchyCore):

Catch `ClassCastException` in `getCompilationUnitNode()` for non-standard
`ICompilationUnit` implementations (e.g. from contributed search
participants) that do not implement the internal compiler interface
(`org.eclipse.jdt.internal.compiler.env.ICompilationUnit`) required by
`ASTParser.createAST()`. Returns null to fall through to the participant
path.

Dependency:

Bump `org.eclipse.jdt.core` dependency to `[3.46.0,4.0.0)` for the
`SearchEngine.getSearchParticipants()` and `SearchParticipant.locateCallees()`
APIs added in eclipse-jdt/eclipse.jdt.core#4938.

Depends on eclipse-jdt/eclipse.jdt.core#4938.
Companion to eclipse-jdtls/eclipse.jdt.ls#3732.
@arcivanov arcivanov force-pushed the feature/search-participant-extension-point branch from 45c547c to 3a3a770 Compare March 21, 2026 18:23
@fbricon
Copy link
Copy Markdown
Contributor

fbricon commented Mar 24, 2026

None of these trigger ECJ compilation. Your concern is based on the javaSource content type behavior you observed in PR #3666, but javaDerivedSource is specifically designed to avoid that problem.

Does it make sense or I'm missing something?

Fair enough. Now do we still need this PR if you're making changes in upstream JDT Core? It's still unclear to me how indexing is supposed to be triggerd

@arcivanov
Copy link
Copy Markdown
Author

arcivanov commented Mar 24, 2026

Yes, this is a part of 3 PRs. Give me another few days please I'm literally testing the end-to-end the Kotlin plugin for JDTLS right now:

https://github.com/karellen/karellen-jdtls-kotlin/
https://github.com/karellen/karellen-jdtls/

@fbricon also in case you missed it eclipse-jdt/eclipse.jdt.core#4938 and eclipse-jdt/eclipse.jdt.ui#2881

@arcivanov arcivanov force-pushed the feature/search-participant-extension-point branch 2 times, most recently from c6dfc6f to 0e2fa76 Compare March 27, 2026 16:57
arcivanov added a commit to arcivanov/eclipse.jdt.ui that referenced this pull request Mar 30, 2026
Incoming calls (CallerMethodWrapper):

Replace hardcoded `new SearchParticipant[] { getDefaultSearchParticipant() }`
with `SearchEngine.getSearchParticipants()` so that incoming call searches
include results from contributed search participants registered via the
`org.eclipse.jdt.core.searchParticipant` extension point. For contributed
(non-Java) elements, accept A_INACCURATE matches since JDT's MatchLocator
cannot resolve type bindings for types not compiled by ECJ.

Outgoing calls (CalleeMethodWrapper):

When the member has no Java AST (i.e. `getCompilationUnitNode()` returns
null), fall back to `SearchParticipant.locateCallees()` on all contributed
participants. Each participant can report call sites within the member's
body. Returned callees are resolved to full declarations via
`resolveCallee()`, which handles METHOD, FIELD, and TYPE element types.

Outgoing calls from Java to non-Java targets (CalleeAnalyzerVisitor):

When a Java method invocation has a null ECJ binding (receiver type is from
a contributed language, not compiled by ECJ), fall back to resolveViaSearch()
which uses SearchEngine.getSearchParticipants() to find METHOD DECLARATIONS
matching the method name across all contributed participants.

Non-standard ICompilationUnit handling (CallHierarchyCore):

Guard getCompilationUnitNode() with isJavaLikeFileName() check so non-Java
source files (e.g. .kt) are not parsed as Java AST, which would produce
broken results and false positives in outgoing call analysis.

Dependency:

Bump `org.eclipse.jdt.core` dependency to `[3.46.0,4.0.0)` for the
`SearchEngine.getSearchParticipants()` and `SearchParticipant.locateCallees()`
APIs added in eclipse-jdt/eclipse.jdt.core#4938.

Depends on eclipse-jdt/eclipse.jdt.core#4938.
Companion to eclipse-jdtls/eclipse.jdt.ls#3732.
@arcivanov arcivanov force-pushed the feature/search-participant-extension-point branch 2 times, most recently from 7a1496b to 4827d80 Compare March 30, 2026 18:02
@arcivanov arcivanov force-pushed the feature/search-participant-extension-point branch 2 times, most recently from 474223d to 9ab78e6 Compare March 31, 2026 07:05
@arcivanov arcivanov force-pushed the feature/search-participant-extension-point branch from 9ab78e6 to 276a7f1 Compare May 5, 2026 20:47
arcivanov added a commit to arcivanov/eclipse.jdt.ui that referenced this pull request May 5, 2026
Incoming calls (CallerMethodWrapper):

Replace hardcoded `new SearchParticipant[] { getDefaultSearchParticipant() }`
with `SearchEngine.getSearchParticipants()` so that incoming call searches
include results from contributed search participants registered via the
`org.eclipse.jdt.core.searchParticipant` extension point. For contributed
(non-Java) elements, accept A_INACCURATE matches since JDT's MatchLocator
cannot resolve type bindings for types not compiled by ECJ.

Outgoing calls (CalleeMethodWrapper):

When the member has no Java AST (i.e. `getCompilationUnitNode()` returns
null), fall back to `SearchParticipant.locateCallees()` on all contributed
participants. Each participant can report call sites within the member's
body. Returned callees are resolved to full declarations via
`resolveCallee()`, which handles METHOD, FIELD, and TYPE element types.

Outgoing calls from Java to non-Java targets (CalleeAnalyzerVisitor):

When a Java method invocation has a null ECJ binding (receiver type is from
a contributed language, not compiled by ECJ), fall back to resolveViaSearch()
which uses SearchEngine.getSearchParticipants() to find METHOD DECLARATIONS
matching the method name across all contributed participants.

Non-standard ICompilationUnit handling (CallHierarchyCore):

Guard getCompilationUnitNode() with isJavaLikeFileName() check so non-Java
source files (e.g. .kt) are not parsed as Java AST, which would produce
broken results and false positives in outgoing call analysis.

Dependency:

Bump `org.eclipse.jdt.core` dependency to `[3.46.0,4.0.0)` for the
`SearchEngine.getSearchParticipants()` and `SearchParticipant.locateCallees()`
APIs added in eclipse-jdt/eclipse.jdt.core#4938.

Depends on eclipse-jdt/eclipse.jdt.core#4938.
Companion to eclipse-jdtls/eclipse.jdt.ls#3732.
@arcivanov arcivanov force-pushed the feature/search-participant-extension-point branch from 276a7f1 to ab95b2e Compare May 6, 2026 06:31
SearchEngine.search() already supports multiple SearchParticipant instances,
but all call sites in jdtls hardcode a single-element array containing only
the default Java participant. This prevents non-Java languages from
contributing index entries for cross-language call hierarchy, find references,
type hierarchy, workspace symbol, and implementation search.

This change updates all four search call sites (ReferencesHandler,
CodeLensHandler, ImplementationCollector, HoverInfoProvider) to use the new
JDT Core API SearchEngine.getSearchParticipants(), which returns the default
participant plus any participants contributed via the
org.eclipse.jdt.core.searchParticipant extension point.

WorkspaceSymbolHandler: supplement searchAllTypeNames() results with a
search() call through contributed participants. searchAllTypeNames() only
queries the default (Java) participant's indexes, making non-Java types
invisible to workspace/symbol queries. The supplementary search creates a
TYPE DECLARATIONS pattern with the same match rule (camelcase or wildcard)
and runs it through contributed participants only, converting SearchMatch
results to SymbolInformation with proper location, container, and kind.

ReferencesHandler: accept A_INACCURATE matches for contributed (non-Java)
elements, since JDT's MatchLocator cannot resolve type bindings for types
not compiled by ECJ.

TypeHierarchyHandler: supplement JDT's native type hierarchy with contributed
search participants. For subtypes, run a supplementary IMPLEMENTORS search
via contributed participants to discover non-Java types that extend or
implement the target type. For supertypes of contributed types, resolve
declared supertype names via type declaration search since JDT's
newSupertypeHierarchy() does not work for non-Java IType implementations.
Re-resolve contributed elements via codeSelect when JavaCore.create() cannot
reconstitute them from handle identifiers.

HoverInfoProvider: use SearchParticipantRegistry.getLanguageId() to tag
hover MarkedString content with the correct LSP language identifier (e.g.
"kotlin" instead of "java") for elements from contributed search
participants.

JDTUtils.resolveCompilationUnit(IFile) now falls back to querying contributed
SearchParticipant.getCompilationUnit(IFile) for non-Java source files,
enabling document symbols, hover, go-to-definition, call hierarchy, and code
lenses for derived source languages (e.g., Kotlin .kt files).

JDTUtils.findElementsAtSelection() now falls back to searching contributed
participants when Java's codeSelect() returns empty. This enables
go-to-definition and hover for types and methods provided by non-Java
languages (e.g., Kotlin facade classes and property accessors) from Java
source files.

NavigateToDefinitionHandler.computeBreakContinue() now guarded with
isJavaLikeFileName check to prevent ClassCastException when ASTParser
attempts to cast a contributed ICompilationUnit (e.g. KotlinCompilationUnit)
to ECJ's internal ICompilationUnit interface.

BaseJDTLanguageServer.computeAsync() and JDTLanguageServer
.computeAsyncWithClientProgress() now log unhandled exceptions via
whenComplete() instead of silently swallowing them, making failures in LSP
request handlers visible in the server log.

When no extensions are registered, behavior is identical to before (only the
default Java participant is used), ensuring zero regression risk.
@arcivanov arcivanov force-pushed the feature/search-participant-extension-point branch from ab95b2e to de9d34b Compare May 6, 2026 06:31
arcivanov added a commit to karellen/karellen-jdtls-kotlin that referenced this pull request May 6, 2026
## Summary

- `matchesTypeName()`, `matchesTypeAliasName()`, and
`locateFacadeTypeMatch()` now use `TypeDeclarationPattern.matchesName()`
instead of `equalsIgnoreCase`, supporting all JDT match rules (exact,
prefix, camelcase, wildcard)
- Adds `WorkspaceSymbolSearchTest` (8 tests) validating workspace/symbol
search for Kotlin types

## Motivation

Workspace/symbol queries (`workspace/symbol` LSP method) use
`R_CAMELCASE_MATCH` and `R_PATTERN_MATCH`. The index correctly selected
documents containing matching Kotlin types, but `locateMatches()`
rejected all declarations because the name comparison used
`equalsIgnoreCase` — only exact matches passed.

`TypeDeclarationPattern.matchesName()` is the same method JDT Core uses
in `matchesDecodedKey()` during index queries. It respects the pattern's
match rule, handling camelcase (e.g., "IPS" →
`InventoryPopulationService`), wildcards (e.g., `*Population*`), prefix,
and exact matching.

Companion fix:
[eclipse.jdt.ls#3732](eclipse-jdtls/eclipse.jdt.ls#3732)
supplements `WorkspaceSymbolHandler.searchAllTypeNames()` with a
`search()` call through contributed participants, since
`searchAllTypeNames` only queries the default Java participant's
indexes.

## Test plan

- [x] `testSearchAllTypeNamesDoesNotFindKotlinTypes` — confirms
`searchAllTypeNames` gap
- [x] `testSearchAllTypeNamesCamelCaseDoesNotFindKotlinTypes` — confirms
camelcase gap
- [x] `testSearchWithParticipantsFindsKotlinTypeExact` — exact match via
`search()`
- [x] `testSearchWithParticipantsFindsKotlinTypeCamelCase` — "IPS" finds
`InventoryPopulationService`
- [x] `testSearchWithParticipantsFindsKotlinTypePatternMatch` —
`*Population*` finds type
- [x] `testSearchWithParticipantsFindsMultipleKotlinTypes` —
`Inventory*Service` finds 2 types
- [x] `testSearchWithParticipantsFindsKotlinInterface` — "IR" finds
interface + implementation
- [x] `testSearchWithParticipantsFindsKotlinTypeWithPackageQualifier` —
sub-package types found
- [x] Full suite: 362 tests, 0 failures
- [x] E2E verified against real Kotlin project (workspace/symbol for
`InventoryPopulationService` and camelcase `IPS`)
arcivanov added a commit to arcivanov/eclipse.jdt.ui that referenced this pull request May 12, 2026
Incoming calls (CallerMethodWrapper):

Replace hardcoded `new SearchParticipant[] { getDefaultSearchParticipant() }`
with `SearchEngine.getSearchParticipants()` so that incoming call searches
include results from contributed search participants registered via the
`org.eclipse.jdt.core.derivedSourceSearchParticipant` extension point. For
contributed (non-Java) elements, accept A_INACCURATE matches since JDT's
MatchLocator cannot resolve type bindings for types not compiled by ECJ.

Outgoing calls (CalleeMethodWrapper):

When the member has no Java AST (i.e. `getCompilationUnitNode()` returns
null), fall back to `DerivedSourceSearchParticipant.locateCallees()` on all
contributed participants. Each participant can report call sites within the
member's body. Returned callees are resolved to full declarations via
`resolveCallee()`, which handles METHOD, FIELD, and TYPE element types.

Outgoing calls from Java to non-Java targets (CalleeAnalyzerVisitor):

When a Java method invocation has a null ECJ binding (receiver type is from
a contributed language, not compiled by ECJ), fall back to resolveViaSearch()
which uses SearchEngine.getSearchParticipants() to find METHOD DECLARATIONS
matching the method name across all contributed participants.

Non-standard ICompilationUnit handling (CallHierarchyCore):

Guard getCompilationUnitNode() with isJavaLikeFileName() check so non-Java
source files (e.g. .kt) are not parsed as Java AST, which would produce
broken results and false positives in outgoing call analysis.

Dependency:

Bump `org.eclipse.jdt.core` dependency to `[3.46.0,4.0.0)` for the
`SearchEngine.getSearchParticipants()` and
`DerivedSourceSearchParticipant.locateCallees()` APIs added in
eclipse-jdt/eclipse.jdt.core#4938.

Depends on eclipse-jdt/eclipse.jdt.core#4938.
Companion to eclipse-jdtls/eclipse.jdt.ls#3732.
arcivanov added a commit to arcivanov/eclipse.jdt.ui that referenced this pull request May 12, 2026
Incoming calls (CallerMethodWrapper):

Replace hardcoded `new SearchParticipant[] { getDefaultSearchParticipant() }`
with `SearchEngine.getSearchParticipants()` so that incoming call searches
include results from contributed search participants registered via the
`org.eclipse.jdt.core.derivedSourceSearchParticipant` extension point. For
contributed (non-Java) elements, accept A_INACCURATE matches since JDT's
MatchLocator cannot resolve type bindings for types not compiled by ECJ.

Outgoing calls (CalleeMethodWrapper):

When the member has no Java AST (i.e. `getCompilationUnitNode()` returns
null), fall back to `DerivedSourceSearchParticipant.locateCallees()` on all
contributed participants. Each participant can report call sites within the
member's body. Returned callees are resolved to full declarations via
`resolveCallee()`, which handles METHOD, FIELD, and TYPE element types.

Outgoing calls from Java to non-Java targets (CalleeAnalyzerVisitor):

When a Java method invocation has a null ECJ binding (receiver type is from
a contributed language, not compiled by ECJ), fall back to resolveViaSearch()
which uses SearchEngine.getSearchParticipants() to find METHOD DECLARATIONS
matching the method name across all contributed participants.

Non-standard ICompilationUnit handling (CallHierarchyCore):

Guard getCompilationUnitNode() with isJavaLikeFileName() check so non-Java
source files (e.g. .kt) are not parsed as Java AST, which would produce
broken results and false positives in outgoing call analysis.

Dependency:

Bump `org.eclipse.jdt.core` dependency to `[3.46.0,4.0.0)` for the
`SearchEngine.getSearchParticipants()` and
`DerivedSourceSearchParticipant.locateCallees()` APIs added in
eclipse-jdt/eclipse.jdt.core#4938.

Depends on eclipse-jdt/eclipse.jdt.core#4938.
Companion to eclipse-jdtls/eclipse.jdt.ls#3732.
arcivanov added a commit to arcivanov/eclipse.jdt.ui that referenced this pull request May 12, 2026
Incoming calls (CallerMethodWrapper):

Replace hardcoded `new SearchParticipant[] { getDefaultSearchParticipant() }`
with `SearchEngine.getSearchParticipants()` so that incoming call searches
include results from contributed search participants registered via the
`org.eclipse.jdt.core.derivedSourceSearchParticipant` extension point. For
contributed (non-Java) elements, accept A_INACCURATE matches since JDT's
MatchLocator cannot resolve type bindings for types not compiled by ECJ.

Outgoing calls (CalleeMethodWrapper):

When the member has no Java AST (i.e. `getCompilationUnitNode()` returns
null), fall back to `DerivedSourceSearchParticipant.locateCallees()` on all
contributed participants. Each participant can report call sites within the
member's body. Returned callees are resolved to full declarations via
`resolveCallee()`, which handles METHOD, FIELD, and TYPE element types.

Outgoing calls from Java to non-Java targets (CalleeAnalyzerVisitor):

When a Java method invocation has a null ECJ binding (receiver type is from
a contributed language, not compiled by ECJ), fall back to resolveViaSearch()
which uses SearchEngine.getSearchParticipants() to find METHOD DECLARATIONS
matching the method name across all contributed participants.

Non-standard ICompilationUnit handling (CallHierarchyCore):

Guard getCompilationUnitNode() with isJavaLikeFileName() check so non-Java
source files (e.g. .kt) are not parsed as Java AST, which would produce
broken results and false positives in outgoing call analysis.

Dependency:

Bump `org.eclipse.jdt.core` dependency to `[3.46.0,4.0.0)` for the
`SearchEngine.getSearchParticipants()` and
`DerivedSourceSearchParticipant.locateCallees()` APIs added in
eclipse-jdt/eclipse.jdt.core#4938.

Depends on eclipse-jdt/eclipse.jdt.core#4938.
Companion to eclipse-jdtls/eclipse.jdt.ls#3732.
arcivanov added a commit to arcivanov/eclipse.jdt.ui that referenced this pull request May 13, 2026
Incoming calls (CallerMethodWrapper):

Replace hardcoded `new SearchParticipant[] { getDefaultSearchParticipant() }`
with `SearchEngine.getSearchParticipants()` so that incoming call searches
include results from contributed search participants registered via the
`org.eclipse.jdt.core.derivedSourceSearchParticipant` extension point. For
contributed (non-Java) elements, accept A_INACCURATE matches since JDT's
MatchLocator cannot resolve type bindings for types not compiled by ECJ.

Outgoing calls (CalleeMethodWrapper):

When the member has no Java AST (i.e. `getCompilationUnitNode()` returns
null), fall back to `DerivedSourceSearchParticipant.locateCallees()` on all
contributed participants. Each participant can report call sites within the
member's body. Returned callees are resolved to full declarations via
`resolveCallee()`, which handles METHOD, FIELD, and TYPE element types.

Outgoing calls from Java to non-Java targets (CalleeAnalyzerVisitor):

When a Java method invocation has a null ECJ binding (receiver type is from
a contributed language, not compiled by ECJ), fall back to resolveViaSearch()
which uses SearchEngine.getSearchParticipants() to find METHOD DECLARATIONS
matching the method name across all contributed participants.

Non-standard ICompilationUnit handling (CallHierarchyCore):

Guard getCompilationUnitNode() with isJavaLikeFileName() check so non-Java
source files (e.g. .kt) are not parsed as Java AST, which would produce
broken results and false positives in outgoing call analysis.

Dependency:

Bump `org.eclipse.jdt.core` dependency to `[3.46.0,4.0.0)` for the
`SearchEngine.getSearchParticipants()` and
`DerivedSourceSearchParticipant.locateCallees()` APIs added in
eclipse-jdt/eclipse.jdt.core#4938.

Depends on eclipse-jdt/eclipse.jdt.core#4938.
Companion to eclipse-jdtls/eclipse.jdt.ls#3732.
arcivanov added a commit to arcivanov/eclipse.jdt.ui that referenced this pull request May 13, 2026
Incoming calls (CallerMethodWrapper):

Replace hardcoded `new SearchParticipant[] { getDefaultSearchParticipant() }`
with `SearchEngine.getSearchParticipants()` so that incoming call searches
include results from contributed search participants registered via the
`org.eclipse.jdt.core.derivedSourceSearchParticipant` extension point. For
contributed (non-Java) elements, accept A_INACCURATE matches since JDT's
MatchLocator cannot resolve type bindings for types not compiled by ECJ.

Outgoing calls (CalleeMethodWrapper):

When the member has no Java AST (i.e. `getCompilationUnitNode()` returns
null), fall back to `DerivedSourceSearchParticipant.locateCallees()` on all
contributed participants. Each participant can report call sites within the
member's body. Returned callees are resolved to full declarations via
`resolveCallee()`, which handles METHOD, FIELD, and TYPE element types.

Outgoing calls from Java to non-Java targets (CalleeAnalyzerVisitor):

When a Java method invocation has a null ECJ binding (receiver type is from
a contributed language, not compiled by ECJ), fall back to resolveViaSearch()
which uses SearchEngine.getSearchParticipants() to find METHOD DECLARATIONS
matching the method name across all contributed participants.

Non-standard ICompilationUnit handling (CallHierarchyCore):

Guard getCompilationUnitNode() with isJavaLikeFileName() check so non-Java
source files (e.g. .kt) are not parsed as Java AST, which would produce
broken results and false positives in outgoing call analysis.

Dependency:

Bump `org.eclipse.jdt.core` dependency to `[3.46.0,4.0.0)` for the
`SearchEngine.getSearchParticipants()` and
`DerivedSourceSearchParticipant.locateCallees()` APIs added in
eclipse-jdt/eclipse.jdt.core#4938.

Depends on eclipse-jdt/eclipse.jdt.core#4938.
Companion to eclipse-jdtls/eclipse.jdt.ls#3732.
jjohnstn pushed a commit to eclipse-jdt/eclipse.jdt.ui that referenced this pull request May 13, 2026
* Use contributed search participants in call hierarchy

Incoming calls (CallerMethodWrapper):

Replace hardcoded `new SearchParticipant[] { getDefaultSearchParticipant() }`
with `SearchEngine.getSearchParticipants()` so that incoming call searches
include results from contributed search participants registered via the
`org.eclipse.jdt.core.derivedSourceSearchParticipant` extension point. For
contributed (non-Java) elements, accept A_INACCURATE matches since JDT's
MatchLocator cannot resolve type bindings for types not compiled by ECJ.

Outgoing calls (CalleeMethodWrapper):

When the member has no Java AST (i.e. `getCompilationUnitNode()` returns
null), fall back to `DerivedSourceSearchParticipant.locateCallees()` on all
contributed participants. Each participant can report call sites within the
member's body. Returned callees are resolved to full declarations via
`resolveCallee()`, which handles METHOD, FIELD, and TYPE element types.

Outgoing calls from Java to non-Java targets (CalleeAnalyzerVisitor):

When a Java method invocation has a null ECJ binding (receiver type is from
a contributed language, not compiled by ECJ), fall back to resolveViaSearch()
which uses SearchEngine.getSearchParticipants() to find METHOD DECLARATIONS
matching the method name across all contributed participants.

Non-standard ICompilationUnit handling (CallHierarchyCore):

Guard getCompilationUnitNode() with isJavaLikeFileName() check so non-Java
source files (e.g. .kt) are not parsed as Java AST, which would produce
broken results and false positives in outgoing call analysis.

Dependency:

Bump `org.eclipse.jdt.core` dependency to `[3.46.0,4.0.0)` for the
`SearchEngine.getSearchParticipants()` and
`DerivedSourceSearchParticipant.locateCallees()` APIs added in
eclipse-jdt/eclipse.jdt.core#4938.

Depends on eclipse-jdt/eclipse.jdt.core#4938.
Companion to eclipse-jdtls/eclipse.jdt.ls#3732.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants