mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[javadoc] Add navigation for fragment references
#IDEA-376337 Fixed GitOrigin-RevId: e56328231c555d8cf4a75a93b107a1e284f15c73
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f421f79436
commit
bfe0d574ab
@@ -1,10 +1,12 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.impl;
|
||||
|
||||
import com.intellij.application.options.CodeStyle;
|
||||
import com.intellij.codeInsight.javadoc.JavaDocInfoGenerator;
|
||||
import com.intellij.codeInsight.javadoc.JavaSuperTypeSearchUtil;
|
||||
import com.intellij.codeInsight.javadoc.SnippetMarkup;
|
||||
import com.intellij.codeInsight.javadoc.index.JavaDocFragmentAnchorCacheKt;
|
||||
import com.intellij.codeInsight.javadoc.index.JavaDocFragmentData;
|
||||
import com.intellij.ide.fileTemplates.FileTemplate;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.ide.fileTemplates.JavaTemplateUtil;
|
||||
@@ -45,6 +47,7 @@ import com.intellij.psi.codeStyle.arrangement.MemberOrderService;
|
||||
import com.intellij.psi.impl.compiled.ClsClassImpl;
|
||||
import com.intellij.psi.impl.compiled.ClsElementImpl;
|
||||
import com.intellij.psi.impl.source.codeStyle.ImportHelper;
|
||||
import com.intellij.psi.impl.source.javadoc.PsiDocFragmentName;
|
||||
import com.intellij.psi.impl.source.javadoc.PsiSnippetAttributeValueImpl;
|
||||
import com.intellij.psi.javadoc.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
@@ -53,9 +56,11 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import kotlin.Pair;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
@@ -445,6 +450,37 @@ public class JavaPsiImplementationHelperImpl extends JavaPsiImplementationHelper
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable PsiSymbolReference getFragmentNameSymbol(@NotNull PsiDocFragmentName fragmentName) {
|
||||
if (DumbService.getInstance(myProject).isDumb()) return null;
|
||||
|
||||
final Pair<PsiClass, JavaDocFragmentData> fragmentData = JavaDocFragmentAnchorCacheKt.getAnchor(myProject, fragmentName);
|
||||
if (fragmentData == null) return null;
|
||||
final int offset = fragmentData.getSecond().getOffset();
|
||||
|
||||
final PsiElement target = fragmentData.getFirst().getContainingFile().getViewProvider().findElementAt(offset);
|
||||
if (!(target instanceof PsiDocToken)) return null;
|
||||
|
||||
return new PsiSymbolReference() {
|
||||
@Override
|
||||
public @NotNull PsiElement getElement() {
|
||||
return fragmentName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TextRange getRangeInElement() {
|
||||
return new TextRange(0, fragmentName.getText().length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull @Unmodifiable Collection<? extends Symbol> resolveReference() {
|
||||
return List.of(
|
||||
new SnippetRegionSymbol(target.getContainingFile(), new TextRange(offset, offset + fragmentName.getText().length()))
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static final class SnippetRegionSymbol implements Symbol, DocumentationTarget, NavigationTarget {
|
||||
|
||||
private final @NotNull PsiFile myFile;
|
||||
|
||||
+15
@@ -3,8 +3,11 @@ package com.intellij.codeInsight.javadoc.index
|
||||
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.impl.source.javadoc.PsiDocFragmentName
|
||||
import com.intellij.psi.javadoc.PsiDocComment
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.util.indexing.ID
|
||||
@@ -64,4 +67,16 @@ private class JavaDocFragmentCacheService {
|
||||
|
||||
fun getAnchors(project: Project, fqnOrPackage: String): LinkedHashSet<JavaDocFragmentData> {
|
||||
return project.service<JavaDocFragmentCacheService>().getAnchors(project, fqnOrPackage)
|
||||
}
|
||||
|
||||
fun getAnchor(project: Project, fragmentName: PsiDocFragmentName): Pair<PsiClass, JavaDocFragmentData>? {
|
||||
if (DumbService.getInstance(project).isDumb) return null
|
||||
|
||||
val psiClass = fragmentName.getScope()
|
||||
val fqn = psiClass?.qualifiedName ?: return null
|
||||
|
||||
val data = getAnchors(project, fqn).firstOrNull { data: JavaDocFragmentData -> data.name == fragmentName.text }
|
||||
?: return null
|
||||
|
||||
return psiClass to data
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.core;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
@@ -9,6 +9,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.JavaPsiImplementationHelper;
|
||||
import com.intellij.psi.impl.source.javadoc.PsiDocFragmentName;
|
||||
import com.intellij.psi.javadoc.PsiDocToken;
|
||||
import com.intellij.psi.javadoc.PsiSnippetAttributeValue;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
@@ -85,6 +86,11 @@ public class CoreJavaPsiImplementationHelper extends JavaPsiImplementationHelper
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable PsiSymbolReference getFragmentNameSymbol(@NotNull PsiDocFragmentName token) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public @NotNull Project getProject() {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.impl;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
@@ -7,6 +7,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.javadoc.PsiDocFragmentName;
|
||||
import com.intellij.psi.javadoc.PsiDocToken;
|
||||
import com.intellij.psi.javadoc.PsiSnippetAttributeValue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -42,4 +43,9 @@ public abstract class JavaPsiImplementationHelper {
|
||||
* This makes it possible to navigate to the inherited doc.
|
||||
*/
|
||||
public abstract @NotNull PsiSymbolReference getInheritDocSymbol(@NotNull PsiDocToken token);
|
||||
|
||||
/**
|
||||
* Returns a PsiSymbolReference mapping a fragment reference ({@code ##fragment-id}) to its source ({@code <p id="fragment-id">…</p>}).
|
||||
*/
|
||||
public abstract @Nullable PsiSymbolReference getFragmentNameSymbol(@NotNull PsiDocFragmentName token);
|
||||
}
|
||||
@@ -1,12 +1,20 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.impl.source.javadoc;
|
||||
|
||||
import com.intellij.model.psi.PsiSymbolReference;
|
||||
import com.intellij.psi.JavaElementVisitor;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.impl.JavaPsiImplementationHelper;
|
||||
import com.intellij.psi.impl.source.Constants;
|
||||
import com.intellij.psi.impl.source.tree.CompositePsiElement;
|
||||
import com.intellij.psi.javadoc.PsiDocTagValue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public class PsiDocFragmentName extends CompositePsiElement implements PsiDocTagValue, Constants {
|
||||
public PsiDocFragmentName() {
|
||||
@@ -22,4 +30,19 @@ public class PsiDocFragmentName extends CompositePsiElement implements PsiDocTag
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable PsiClass getScope() {
|
||||
final PsiElement parent = getParent();
|
||||
return parent instanceof PsiDocFragmentRef ? ((PsiDocFragmentRef)parent).getScope() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<? extends @NotNull PsiSymbolReference> getOwnReferences() {
|
||||
final PsiSymbolReference symbolReference = JavaPsiImplementationHelper
|
||||
.getInstance(getProject())
|
||||
.getFragmentNameSymbol(this);
|
||||
|
||||
if (symbolReference != null) return Collections.singleton(symbolReference);
|
||||
return super.getOwnReferences();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user