1.9 Add project-view-tree-comment for "xx ClassNameOrSimpleName.json" and SPI file | 增加 "xx 类全名或简名.json" 和 SPI 项目导航栏注释
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package io.github.linwancen.plugin.show.doc;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -36,12 +37,26 @@ public class DocUtils {
|
||||
@Nullable
|
||||
public static PsiDocComment fileDoc(PsiFile psiFile) {
|
||||
if (!(psiFile instanceof PsiClassOwner)) {
|
||||
// for SPI
|
||||
PsiClass[] psiClasses = PsiClassUtils.nameToClass(psiFile.getName(), psiFile.getProject());
|
||||
// for "xxx ClassName.xxx"
|
||||
if (psiClasses.length == 0) {
|
||||
VirtualFile virtualFile = psiFile.getVirtualFile();
|
||||
psiClasses = PsiClassUtils.encClass(virtualFile, psiFile.getProject());
|
||||
}
|
||||
for (PsiClass psiClass : psiClasses) {
|
||||
PsiDocComment docComment = srcOrByteCodeDoc(psiClass);
|
||||
if (docComment != null) {
|
||||
// Inaccurate when there are classes with the same name
|
||||
return docComment;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
PsiClassOwner psiClassOwner = (PsiClassOwner) psiFile;
|
||||
if (PsiPackage.PACKAGE_INFO_FILE.equals(psiFile.getName())) {
|
||||
return PackageDocUtils.fromPackageInfoFile(psiFile);
|
||||
}
|
||||
PsiClassOwner psiClassOwner = (PsiClassOwner) psiFile;
|
||||
PsiClass[] classes = psiClassOwner.getClasses();
|
||||
if (classes.length == 0) {
|
||||
return null;
|
||||
|
||||
@@ -2,22 +2,17 @@ package io.github.linwancen.plugin.show.doc;
|
||||
|
||||
import com.intellij.json.psi.JsonProperty;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiShortNamesCache;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class JsonDocUtils {
|
||||
private static final Pattern JSON_PATTERN = Pattern.compile("[\\w.]*+$");
|
||||
|
||||
private JsonDocUtils() {}
|
||||
|
||||
@@ -27,60 +22,56 @@ public class JsonDocUtils {
|
||||
if (jsonProp == null || jsonProp.getNameElement().getTextRange().getEndOffset() > endOffset) {
|
||||
return null;
|
||||
}
|
||||
String fileName = element.getContainingFile().getVirtualFile().getNameWithoutExtension();
|
||||
Matcher matcher = JSON_PATTERN.matcher(fileName);
|
||||
if (!matcher.find()) {
|
||||
return null;
|
||||
}
|
||||
String className = matcher.group();
|
||||
PsiClass[] psiClasses = classByName(className, element.getProject());
|
||||
PsiField psiField = psiField(psiClasses, element.getProject(), jsonProp);
|
||||
if (psiField != null) {
|
||||
return DocUtils.srcOrByteCodeDoc(psiField);
|
||||
}
|
||||
return null;
|
||||
VirtualFile virtualFile = element.getContainingFile().getVirtualFile();
|
||||
PsiClass[] psiClasses = PsiClassUtils.encClass(virtualFile, element.getProject());
|
||||
List<String> jsonPath = jsonPath(jsonProp);
|
||||
return doc(psiClasses, element.getProject(), jsonPath, jsonPath.size() - 1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiClass[] classByName(String className, @NotNull Project project) {
|
||||
int i = className.indexOf('.');
|
||||
if (i > 0) {
|
||||
return classByFullName(className, project);
|
||||
}
|
||||
PsiShortNamesCache namesCache = PsiShortNamesCache.getInstance(project);
|
||||
return namesCache.getClassesByName(className, GlobalSearchScope.allScope(project));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiClass[] classByFullName(String className, @NotNull Project project) {
|
||||
JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
|
||||
return javaPsiFacade.findClasses(className, GlobalSearchScope.allScope(project));
|
||||
public static List<String> jsonPath(JsonProperty jsonProp) {
|
||||
ArrayList<String> jsonPath = new ArrayList<>();
|
||||
do {
|
||||
jsonPath.add(jsonProp.getName());
|
||||
} while ((jsonProp = PsiTreeUtil.getParentOfType(jsonProp, JsonProperty.class)) != null);
|
||||
return jsonPath;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiField psiField(PsiClass[] rootClasses, Project project, JsonProperty jsonProp) {
|
||||
JsonProperty parentJsonProp = PsiTreeUtil.getParentOfType(jsonProp, JsonProperty.class);
|
||||
if (parentJsonProp == null) {
|
||||
for (PsiClass c : rootClasses) {
|
||||
PsiField field = c.findFieldByName(jsonProp.getName(), true);
|
||||
if (field != null) {
|
||||
return field;
|
||||
}
|
||||
private static PsiDocComment doc(PsiClass[] psiClasses, Project project, List<String> jsonPath, int level) {
|
||||
String name = jsonPath.get(level);
|
||||
for (PsiClass psiClass : psiClasses) {
|
||||
PsiField psiField = psiClass.findFieldByName(name, true);
|
||||
if (psiField == null) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
PsiField psiField = psiField(rootClasses, project, parentJsonProp);
|
||||
if (psiField == null) {
|
||||
return null;
|
||||
}
|
||||
String classFullName = psiField.getType().getCanonicalText();
|
||||
@NotNull PsiClass[] psiClasses = classByFullName(classFullName, project);
|
||||
for (PsiClass c : psiClasses) {
|
||||
PsiField field = c.findFieldByName(jsonProp.getName(), true);
|
||||
if (field != null) {
|
||||
return field;
|
||||
if (level == 0) {
|
||||
return DocUtils.srcOrByteCodeDoc(psiField);
|
||||
}
|
||||
String classFullName = toClassFullName(psiField);
|
||||
PsiClass[] classes = PsiClassUtils.fullNameToClass(classFullName, project);
|
||||
PsiDocComment docComment = doc(classes, project, jsonPath, level - 1);
|
||||
if (docComment != null) {
|
||||
return docComment;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String toClassFullName(PsiField psiField) {
|
||||
PsiTypeElement typeElement = psiField.getTypeElement();
|
||||
if (typeElement != null) {
|
||||
PsiJavaCodeReferenceElement code = typeElement.getInnermostComponentReferenceElement();
|
||||
if (code != null) {
|
||||
PsiType[] types = code.getTypeParameters();
|
||||
if (types.length > 0) {
|
||||
// List
|
||||
return types[types.length - 1].getCanonicalText();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Array
|
||||
return psiField.getType().getDeepComponentType().getCanonicalText();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package io.github.linwancen.plugin.show.doc;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiShortNamesCache;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class PsiClassUtils {
|
||||
|
||||
private PsiClassUtils() {}
|
||||
|
||||
private static final Pattern JSON_PATTERN = Pattern.compile("[\\w.]*+$");
|
||||
|
||||
@NotNull
|
||||
public static PsiClass[] encClass(@NotNull VirtualFile virtualFile, @NotNull Project project) {
|
||||
String fileName = virtualFile.getNameWithoutExtension();
|
||||
Matcher matcher = JSON_PATTERN.matcher(fileName);
|
||||
if (!matcher.find()) {
|
||||
return new PsiClass[0];
|
||||
}
|
||||
String className = matcher.group();
|
||||
return nameToClass(className, project);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiClass[] nameToClass(@Nullable String className, @NotNull Project project) {
|
||||
if (className == null) {
|
||||
return new PsiClass[0];
|
||||
}
|
||||
int i = className.indexOf('.');
|
||||
return i > 0
|
||||
? fullNameToClass(className, project)
|
||||
: simpleNameToClass(className, project);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiClass[] simpleNameToClass(@NotNull String className, @NotNull Project project) {
|
||||
PsiShortNamesCache namesCache = PsiShortNamesCache.getInstance(project);
|
||||
return namesCache.getClassesByName(className, GlobalSearchScope.allScope(project));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiClass[] fullNameToClass(@NotNull String className, @NotNull Project project) {
|
||||
JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
|
||||
return javaPsiFacade.findClasses(className, GlobalSearchScope.allScope(project));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user