1.11 Add json key jump to field | 增加 json 跳转到字段

This commit is contained in:
林万程
2022-03-15 23:31:44 +08:00
parent 3045abd416
commit ac4ed47c9f
8 changed files with 220 additions and 112 deletions

View File

@@ -5,41 +5,45 @@ https://plugins.jetbrains.com/plugin/18553-show-comment
English Notes:
<ul>
<li>Show javadoc comments at the Project view Tree structure.
<li>Show javadoc comments at the end-of-line.
<li>Show javadoc comments at "xx ClassNameOrSimpleName.json".
<li>Show javadoc comments at the Project view Tree structure
<li>Show javadoc comments at the end-of-line
<li>Show javadoc comments at "xx ClassNameOrSimpleName.json" and jump to field
<li>Config: settings -> Tools -> Show Comment Global/Project
</ul>
Chinese Notes:
<ul>
<li>在结构树显示 文档注释
<li>在行末尾显示 文档注释
<li>支持 "xx 类全名或简名.json"
<li>在结构树显示 文档注释
<li>在行末尾显示 文档注释
<li>支持 "xx 类全名或简名.json" 文档注释与跳转到字段
<li>修改配置:设置 -> 工具 -> Show Comment Global/Project
</ul>
English Change Notes:
<ul>
<li>1.9 Add project-view-tree-comment for "xx ClassNameOrSimpleName.json" and SPI file
<li>1.8 Add line-end-comment for "xx ClassNameOrSimpleName.json"
<li>1.7 Add line-end-comment setting for prefix and count
<li>1.6 Add line-end-comment independent switch for call, new, ref
<li>1.5 Add line-end-comment find next loop when none
<li>1.4 Add line-end-comment find element right to left
<li>1.3 Add project-view-tree-comment
<li>1.2 Add line-end-comment settings fro class prefix filter
<li>1.1 Add line-end-comment settings for text color
<li>1.11 Add json key jump to field
<li>1.10 Add project-view-tree-comment for package from parent or other project
<li>1.9 Add project-view-tree-comment for "xx ClassNameOrSimpleName.json" and SPI file
<li>1.8 Add line-end-comment for "xx ClassNameOrSimpleName.json"
<li>1.7 Add line-end-comment setting for prefix and count
<li>1.6 Add line-end-comment independent switch for call, new, ref
<li>1.5 Add line-end-comment find next loop when none
<li>1.4 Add line-end-comment find element right to left
<li>1.3 Add project-view-tree-comment
<li>1.2 Add line-end-comment settings fro class prefix filter
<li>1.1 Add line-end-comment settings for text color
</ul>
Chinese Change Notes:
<ul>
<li>1.9 增加 "xx 类全名或简名.json" 和 SPI 项目导航栏注释
<li>1.8 增加 "xx 类全名或简名.json" 行末注释
<li>1.7 增加 行末注释前缀和对象数设置
<li>1.6 增加 行末调用new引用注释独立开关
<li>1.5 增加 没有注释时循环查找下一个对象
<li>1.4 增加 从右往左查找行末注释对象
<li>1.3 增加 项目导航栏注释
<li>1.2 增加 行末注释类前缀配置
<li>1.1 增加 行末文本颜色配置
<li>1.11 增加 json 跳转到字段
<li>1.10 增加 在父包和其他项目的包中获取 项目导航栏注释
<li>1.9 增加 "xx 类全名或简名.json" 和 SPI 项目导航栏注释
<li>1.8 增加 "xx 类全名或简名.json" 行末注释
<li>1.7 增加 行末注释前缀和对象数设置
<li>1.6 增加 行末调用new引用注释独立开关
<li>1.5 增加 没有注释时循环查找下一个对象
<li>1.4 增加 从右往左查找行末注释对象
<li>1.3 增加 项目导航栏注释
<li>1.2 增加 行末注释类前缀配置
<li>1.1 增加 行末文本颜色配置
</ul>

View File

@@ -4,7 +4,7 @@ plugins {
}
group 'io.github.linwancen'
version '1.9.0.' + (new Date().format('yyyy.MM.dd_HH.mm'))
version '1.11.0.' + (new Date().format('yyyy.MM.dd_HH.mm'))
apply plugin: 'java'
@@ -39,28 +39,32 @@ patchPluginXml {
changeNotes = """
English Change Notes:
<ul>
<li>1.9 Add project-view-tree-comment for "xx ClassNameOrSimpleName.json" and SPI file
<li>1.8 Add line-end-comment for "xx ClassNameOrSimpleName.json"
<li>1.7 Add line-end-comment setting for prefix and count
<li>1.6 Add line-end-comment independent switch for call, new, ref
<li>1.5 Add line-end-comment find next loop when none
<li>1.4 Add line-end-comment find element right to left
<li>1.3 Add project-view-tree-comment
<li>1.2 Add line-end-comment settings fro class prefix filter
<li>1.1 Add line-end-comment settings for text color
<li>1.11 Add json key jump to field
<li>1.10 Add project-view-tree-comment for package from parent or other project
<li>1.9 Add project-view-tree-comment for "xx ClassNameOrSimpleName.json" and SPI file
<li>1.8 Add line-end-comment for "xx ClassNameOrSimpleName.json"
<li>1.7 Add line-end-comment setting for prefix and count
<li>1.6 Add line-end-comment independent switch for call, new, ref
<li>1.5 Add line-end-comment find next loop when none
<li>1.4 Add line-end-comment find element right to left
<li>1.3 Add project-view-tree-comment
<li>1.2 Add line-end-comment settings fro class prefix filter
<li>1.1 Add line-end-comment settings for text color
</ul>
Chinese Change Notes:
<ul>
<li>1.9 增加 "xx 类全名或简名.json" 和 SPI 项目导航栏注释
<li>1.8 增加 "xx 类全名或简名.json" 行末注释
<li>1.7 增加 行末注释前缀和对象数设置
<li>1.6 增加 行末调用new引用注释独立开关
<li>1.5 增加 没有注释时循环查找下一个对象
<li>1.4 增加 从右往左查找行末注释对象
<li>1.3 增加 项目导航栏注释
<li>1.2 增加 行末注释类前缀配置
<li>1.1 增加 行末文本颜色配置
<li>1.11 增加 json 跳转到字段
<li>1.10 增加 在父包和其他项目的包中获取 项目导航栏注释
<li>1.9 增加 "xx 类全名或简名.json" 和 SPI 项目导航栏注释
<li>1.8 增加 "xx 类全名或简名.json" 行末注释
<li>1.7 增加 行末注释前缀和对象数设置
<li>1.6 增加 行末调用new引用注释独立开关
<li>1.5 增加 没有注释时循环查找下一个对象
<li>1.4 增加 从右往左查找行末注释对象
<li>1.3 增加 项目导航栏注释
<li>1.2 增加 行末注释类前缀配置
<li>1.1 增加 行末文本颜色配置
</ul>
"""
}

View File

@@ -0,0 +1,72 @@
package io.github.linwancen.plugin.show;
import com.intellij.json.psi.JsonProperty;
import com.intellij.json.psi.JsonStringLiteral;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ProcessingContext;
import io.github.linwancen.plugin.show.doc.PsiClassUtils;
import io.github.linwancen.plugin.show.json.JsonRef;
import io.github.linwancen.plugin.show.json.JsonUtils;
import org.jetbrains.annotations.NotNull;
import java.util.*;
public class JsonJump extends PsiReferenceContributor {
@Override
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(PlatformPatterns.psiElement(JsonStringLiteral.class),
new PsiReferenceProvider() {
@Override
public PsiReference @NotNull [] getReferencesByElement(@NotNull PsiElement element,
@NotNull ProcessingContext context) {
JsonProperty jsonProp = PsiTreeUtil.getParentOfType(element, JsonProperty.class, true);
if (jsonProp == null) {
return PsiReference.EMPTY_ARRAY;
}
VirtualFile virtualFile = element.getContainingFile().getVirtualFile();
if (virtualFile == null) {
return PsiReference.EMPTY_ARRAY;
}
Project project = element.getProject();
List<PsiField> psiFields = new ArrayList<>();
List<PsiField> tips = new ArrayList<>();
PsiClass[] psiClasses = PsiClassUtils.encClass(virtualFile, project);
List<String> jsonPath = JsonUtils.jsonPath(jsonProp);
put(project, psiFields, tips, psiClasses, jsonPath, jsonPath.size() - 1);
List<PsiReference> list = new ArrayList<>();
for (PsiField psiField : psiFields) {
list.add(new JsonRef(element, psiField, tips));
}
return list.toArray(new PsiReference[0]);
}
});
}
private static void put(Project project, List<PsiField> psiFields, List<PsiField> tips,
PsiClass[] psiClasses, List<String> jsonPath, int level) {
String name = jsonPath.get(level);
for (PsiClass psiClass : psiClasses) {
if (level == 1) {
tips.addAll(Arrays.asList(psiClass.getAllFields()));
}
PsiField psiField = psiClass.findFieldByName(name, true);
if (psiField == null) {
continue;
}
if (level == 0) {
psiFields.add(psiField);
} else {
String classFullName = PsiClassUtils.toClassFullName(psiField);
PsiClass[] classes = PsiClassUtils.fullNameToClass(classFullName, project);
put(project, psiFields, tips, classes, jsonPath, level - 1);
}
}
}
}

View File

@@ -1,59 +1,31 @@
package io.github.linwancen.plugin.show.doc;
import com.intellij.json.psi.JsonProperty;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.PsiDocCommentOwner;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class JsonDocUtils {
private JsonDocUtils() {}
/**
* depend on JsonJump
*/
@Nullable
public static PsiDocComment jsonDoc(PsiElement element, int startOffset, int endOffset) {
JsonProperty jsonProp = PsiTreeUtil.getParentOfType(element, JsonProperty.class, true, startOffset);
if (jsonProp == null || jsonProp.getNameElement().getTextRange().getEndOffset() > endOffset) {
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
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 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) {
continue;
}
if (level == 0) {
PsiDocComment docComment = DocUtils.srcOrByteCodeDoc(psiField);
if (docComment != null) {
return docComment;
}
} else {
String classFullName = toClassFullName(psiField);
PsiClass[] classes = PsiClassUtils.fullNameToClass(classFullName, project);
PsiDocComment docComment = doc(classes, project, jsonPath, level - 1);
for (PsiReference reference : jsonProp.getNameElement().getReferences()) {
PsiElement resolve = reference.resolve();
if (resolve instanceof PsiDocCommentOwner) {
PsiDocCommentOwner owner = (PsiDocCommentOwner) resolve;
PsiDocComment docComment = DocUtils.srcOrByteCodeDoc(owner);
if (docComment != null) {
return docComment;
}
@@ -61,26 +33,4 @@ public class JsonDocUtils {
}
return null;
}
@NotNull
private static String toClassFullName(PsiField psiField) {
// <> only in .java
PsiElement navElement = psiField.getNavigationElement();
if (navElement instanceof PsiField) {
psiField = (PsiField) navElement;
}
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();
}
}

View File

@@ -2,8 +2,7 @@ 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.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
import org.jetbrains.annotations.NotNull;
@@ -51,4 +50,18 @@ public class PsiClassUtils {
JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
return javaPsiFacade.findClasses(className, GlobalSearchScope.allScope(project));
}
@NotNull
public static String toClassFullName(PsiField psiField) {
// Array
// use replace simpler than getDeepComponentType()
String typeName = psiField.getType().getCanonicalText().replace("[]", "");
// List
// use substring() because clsFieldImpl.getInnermostComponentReferenceElement() == null
int index = typeName.indexOf("<");
if (index >= 0) {
return typeName.substring(index + 1, typeName.length() - 1);
}
return typeName;
}
}

View File

@@ -0,0 +1,41 @@
package io.github.linwancen.plugin.show.json;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class JsonRef extends PsiReferenceBase<PsiElement> implements PsiPolyVariantReference {
final PsiField psiField;
final List<PsiField> tips;
public JsonRef(@NotNull PsiElement element, @NotNull PsiField psiField, @NotNull List<PsiField> tips) {
super(element);
this.psiField = psiField;
this.tips = tips;
}
/**
* do not use it because PsiReference.resolveReference() is @Experimental
*/
@Override
public ResolveResult @NotNull [] multiResolve(boolean incompleteCode) {
return new ResolveResult[]{new PsiElementResolveResult(psiField)};
}
@Nullable
@Override
public PsiElement resolve() {
return psiField;
}
/**
* I don't know how to use it
*/
@Override
public Object @NotNull [] getVariants() {
return tips.toArray();
}
}

View File

@@ -0,0 +1,22 @@
package io.github.linwancen.plugin.show.json;
import com.intellij.json.psi.JsonProperty;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class JsonUtils {
private JsonUtils() {}
@NotNull
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;
}
}

View File

@@ -6,16 +6,16 @@
<description><![CDATA[
English Notes:
<ul>
<li>Show javadoc comments at the Project view Tree structure.
<li>Show javadoc comments at the end-of-line.
<li>Show javadoc comments at "xx ClassNameOrSimpleName.json".
<li>Show javadoc comments at the Project view Tree structure
<li>Show javadoc comments at the end-of-line
<li>Show javadoc comments at "xx ClassNameOrSimpleName.json" and jump to field
<li>Config: settings -> Tools -> Show Comment Global/Project
</ul>
Chinese Notes:
<ul>
<li>在结构树显示 文档注释
<li>在行末尾显示 文档注释
<li>支持 "xx 类全名或简名.json"
<li>在结构树显示 文档注释
<li>在行末尾显示 文档注释
<li>支持 "xx 类全名或简名.json" 文档注释与跳转到字段
<li>修改配置:设置 -> 工具 -> Show Comment Global/Project
</ul>
]]></description>
@@ -40,6 +40,8 @@ Chinese Notes:
id="io.github.linwancen.plugin.show.settings.ProjectSettingsConfigurable"
displayName="Show Comment Project"/>
<projectService serviceImplementation="io.github.linwancen.plugin.show.settings.ProjectSettingsState"/>
<psi.referenceContributor implementation="io.github.linwancen.plugin.show.JsonJump"/>
</extensions>
<actions>