IDEA-393258 javadoc: Red links when viewing references outside of source code

(cherry picked from commit ceb0485e5ee44b607aff1ec83acd8eb4c79e9f73)

GitOrigin-RevId: cc036a405d21e647d946b0cd82d9bcefcbdbf78f
This commit is contained in:
Mathias Boulay
2026-09-03 09:51:07 +00:00
committed by intellij-monorepo-bot
parent 115bf80ec9
commit 5ba7a3e328
3 changed files with 21 additions and 5 deletions
@@ -531,7 +531,8 @@ public class JavaPsiImplementationHelperImpl extends JavaPsiImplementationHelper
if (fragmentData == null) return null;
final int offset = fragmentData.getSecond().getOffset();
final PsiElement target = fragmentData.getFirst().getContainingFile().getViewProvider().findElementAt(offset);
final PsiElement target =
JavaDocFragmentAnchorCacheKt.getMaybeSourceClass(fragmentData.getFirst()).getContainingFile().getViewProvider().findElementAt(offset);
if (!(target instanceof PsiDocToken)) return null;
return new PsiSymbolReference() {
@@ -5,6 +5,8 @@ import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.compiled.ClsClassImpl
import com.intellij.psi.javadoc.PsiDocComment
import com.intellij.psi.javadoc.PsiDocFragmentName
import com.intellij.psi.util.CachedValueProvider.Result
@@ -28,10 +30,11 @@ private class JavaDocFragmentCacheService {
fun getAnchors(project: Project, psiClass: PsiClass): LinkedHashSet<JavaDocFragmentData> {
val manager = CachedValuesManager.getManager(project)
return manager.getCachedValue(psiClass) {
val targetClass = getMaybeSourceClass(psiClass)
val result = LinkedHashSet<JavaDocFragmentData>().apply {
addAll(findIdsFromComment(psiClass.docComment))
for (method in psiClass.methods) addAll(findIdsFromComment(method.docComment))
for (field in psiClass.fields) addAll(findIdsFromComment(field.docComment))
addAll(findIdsFromComment(targetClass.docComment))
for (method in targetClass.methods) addAll(findIdsFromComment(method.docComment))
for (field in targetClass.fields) addAll(findIdsFromComment(field.docComment))
}
Result.create(result, PsiModificationTracker.MODIFICATION_COUNT)
}
@@ -78,4 +81,15 @@ fun resolveJavaDocFragment(project: Project, fragmentName: PsiDocFragmentName):
?: return null
return psiClass to data
}
/** Returns the source class if available for a given compiled class */
fun getMaybeSourceClass(clazz: PsiClass): PsiClass {
if (clazz is ClsClassImpl) {
val navigationClass: PsiElement = clazz.getNavigationElement()
if (navigationClass is PsiClass) {
return navigationClass
}
}
return clazz
}
@@ -199,7 +199,8 @@ public final class JavaDocUtil {
String fragmentName = refTextCorrected.substring(fragmentIndex + 2);
for (JavaDocFragmentData fragmentData : JavaDocFragmentAnchorCacheKt.getJavaDocFragmentsForClass(manager.getProject(), aClass)) {
if (fragmentName.equals(fragmentData.getName())) {
PsiElement ref = PsiUtilCore.getElementAtOffset(aClass.getContainingFile(), fragmentData.getOffset());
PsiElement ref = PsiUtilCore.getElementAtOffset(JavaDocFragmentAnchorCacheKt.getMaybeSourceClass(aClass).getContainingFile(),
fragmentData.getOffset());
PsiDocComment docComment = PsiTreeUtil.getParentOfType(ref, PsiDocComment.class, false);
if (docComment == null) return null;
PsiElement owner = docComment.getOwner();