2.04 json dict doc from (key).tsv | 从 键名.tsv 中读取 json 的字典注释 fixed #12

This commit is contained in:
林万程
2022-10-30 18:34:23 +08:00
parent 82d0ade99b
commit c6318f88a2
22 changed files with 184 additions and 94 deletions

View File

@@ -42,7 +42,7 @@ public class LineExt {
return null;
}
@NotNull Map<String, Map<String, List<String>>> docMap = ConfCache.docMap(path, name, ext);
@NotNull Map<String, Map<String, List<String>>> treeMap = ConfCache.treeMap(path, name, ext);
@NotNull Map<String, Map<String, List<String>>> treeMap = ConfCache.treeMap(path);
if (docMap.isEmpty() && treeMap.isEmpty()) {
return null;
}

View File

@@ -23,8 +23,7 @@ public class TreeExt {
@Nullable
public static String extDoc(@NotNull VirtualFile file) {
@NotNull Map<String, Map<String, List<String>>> docMap = ConfCache.treeMap(
file.getPath(), file.getName(), file.getPath());
@NotNull Map<String, Map<String, List<String>>> docMap = ConfCache.treeMap(file.getPath());
@NotNull String[] words = {
file.getName(),
file.getNameWithoutExtension(),

View File

@@ -4,8 +4,6 @@ import com.intellij.notification.NotificationDisplayType;
import com.intellij.notification.NotificationGroup;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
@@ -23,9 +21,6 @@ import java.util.regex.Pattern;
*/
public class ConfCache {
private static final Pattern LINE_PATTERN = Pattern.compile("[\\r\\n]++");
static final String EXT = "tsv";
static final String KEY_MID_EXT = ".key";
static final String DOC_MID_EXT = ".doc";
static final String TREE_MID_EXT = ".tree";
@@ -63,10 +58,8 @@ public class ConfCache {
}
@NotNull
public static Map<String, Map<String, List<String>>> treeMap(@NotNull String path,
@NotNull String name,
@Nullable String ext) {
return ConfCacheGetUtils.filterPath(TREE_CACHE, path, name, ext);
public static Map<String, Map<String, List<String>>> treeMap(@NotNull String path) {
return ConfCacheGetUtils.filterPath(TREE_CACHE, path);
}
static void clearAll() {
@@ -117,10 +110,10 @@ public class ConfCache {
static void loadAll(@NotNull Project project) {
DumbService.getInstance(project).runReadActionInSmartMode(() ->
ApplicationManager.getApplication().runReadAction(() -> {
@NotNull Collection<VirtualFile> files = FilenameIndex.getAllFilesByExt(project, EXT);
@NotNull Collection<VirtualFile> files = FilenameIndex.getAllFilesByExt(project, TsvLoader.EXT);
@NotNull StringBuilder sb = new StringBuilder();
for (@NotNull VirtualFile file : files) {
load(project, file);
load(file);
sb.append(file.getName()).append("\n");
}
if (files.isEmpty()) {
@@ -131,33 +124,26 @@ public class ConfCache {
}));
}
static void loadFile(@Nullable Project project, @NotNull VirtualFile file) {
ApplicationManager.getApplication().runReadAction(() -> ConfCache.load(project, file));
static void loadFile(@NotNull VirtualFile file) {
ApplicationManager.getApplication().runReadAction(() -> ConfCache.load(file));
}
private static void load(@Nullable Project project, @NotNull VirtualFile file) {
if (!ConfCache.EXT.equals(file.getExtension())) {
private static void load(@NotNull VirtualFile file) {
if (!TsvLoader.EXT.equals(file.getExtension())) {
return;
}
@Nullable Document document = FileDocumentManager.getInstance().getDocument(file);
if (document == null) {
return;
}
@NotNull String text = document.getText();
@NotNull String name = file.getNameWithoutExtension();
// this pattern would skip empty line
String[] lines = LINE_PATTERN.split(text);
if (name.endsWith(KEY_MID_EXT)) {
@NotNull String matchName = name.substring(0, name.length() - KEY_MID_EXT.length());
int i = matchName.lastIndexOf(".");
if (i > 0) {
EXT_IN_KEY_CACHE.add(matchName.substring(i + 1));
}
KEY_CACHE.put(file, ConfFactory.buildMap(project, file.getPath(), lines, true));
KEY_CACHE.put(file, TsvLoader.buildMap(file, true));
} else if (name.endsWith(DOC_MID_EXT)) {
DOC_CACHE.put(file, ConfFactory.buildMap(project, file.getPath(), lines, false));
DOC_CACHE.put(file, TsvLoader.buildMap(file, false));
} else if (name.endsWith(TREE_MID_EXT)) {
TREE_CACHE.put(file, ConfFactory.buildMap(project, file.getPath(), lines, false));
TREE_CACHE.put(file, TsvLoader.buildMap(file, false));
}
}
}

View File

@@ -6,9 +6,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
class ConfCacheGetUtils {
public class ConfCacheGetUtils {
private static final String SKIP_PATH = "doc";
private static final String MATCH_STR = "%";
@@ -73,9 +74,7 @@ class ConfCacheGetUtils {
* @return {@code <sortKey, T>}
*/
@NotNull
static <T> TreeMap<String, T> filterPath(@SuppressWarnings("SameParameterValue")
@NotNull Map<VirtualFile, T> cache,
@NotNull String path, String name, String ext) {
public static <T> SortedMap<String, T> filterPath(@NotNull Map<VirtualFile, T> cache, @NotNull String path) {
@NotNull TreeMap<String, T> map = new TreeMap<>();
int max = path.length();
int length = String.valueOf(max).length();

View File

@@ -1,16 +1,13 @@
package io.github.linwancen.plugin.show.ext.conf;
import com.google.common.base.Splitter;
import com.intellij.notification.NotificationDisplayType;
import com.intellij.notification.NotificationGroup;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.project.Project;
import com.twelvemonkeys.util.LinkedSet;
import groovy.json.StringEscapeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -68,30 +65,4 @@ class ConfFactory {
return null;
}
}
public static final Pattern DEL_PATTERN = Pattern.compile("\\(\\?[^)]++\\)");
@NotNull
static Map<String, List<String>> buildMap(@Nullable Project project, @NotNull String path,
@NotNull String[] lines, boolean isKey) {
@NotNull Map<String, List<String>> map = new LinkedHashMap<>();
for (@NotNull String line : lines) {
@NotNull List<String> words = Splitter.on('\t').splitToList(line);
if (!words.isEmpty()) {
String key = words.get(0);
if (key.length() == 0) {
continue;
}
if (isKey) {
key = StringEscapeUtils.unescapeJava(key);
String del = DEL_PATTERN.matcher(key).replaceAll("");
if (del.length() != 0) {
key = del;
}
}
map.put(key, words);
}
}
return map;
}
}

View File

@@ -18,7 +18,7 @@ public class ConfFileChangeListener implements FileEditorManagerListener {
return;
}
if (file.exists()) {
ConfCache.loadFile(event.getManager().getProject(), file);
ConfCache.loadFile(file);
}
}
}

View File

@@ -29,13 +29,13 @@ public class ConfFileListener implements BulkFileListener {
@NotNull VFilePropertyChangeEvent changeEvent = (VFilePropertyChangeEvent) event;
if ("name".equals(changeEvent.getPropertyName())) {
String oldName = changeEvent.getOldValue().toString();
if (oldName.endsWith(ConfCache.EXT)) {
if (oldName.endsWith(TsvLoader.EXT)) {
// change cache too complicated so remove
ConfCache.remove(file, oldName);
}
}
}
if (!ConfCache.EXT.equals(file.getExtension())) {
if (!TsvLoader.EXT.equals(file.getExtension())) {
return;
}
if (event instanceof VFileMoveEvent) {
@@ -60,6 +60,6 @@ public class ConfFileListener implements BulkFileListener {
}
// VFileCreateEvent
// VFileContentChangeEvent
ConfCache.loadFile(null, file);
ConfCache.loadFile(file);
}
}

View File

@@ -0,0 +1,54 @@
package io.github.linwancen.plugin.show.ext.conf;
import com.google.common.base.Splitter;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.vfs.VirtualFile;
import groovy.json.StringEscapeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
public class TsvLoader {
private TsvLoader() {}
public static final String EXT = "tsv";
private static final Pattern LINE_PATTERN = Pattern.compile("[\\r\\n]++");
public static final Pattern DEL_PATTERN = Pattern.compile("\\(\\?[^)]++\\)");
@NotNull
public static Map<String, List<String>> buildMap(@NotNull VirtualFile file, boolean patternKey) {
@Nullable Document document = FileDocumentManager.getInstance().getDocument(file);
if (document == null) {
return Collections.emptyMap();
}
@NotNull String text = document.getText();
// this pattern would skip empty line
String[] lines = LINE_PATTERN.split(text);
@NotNull Map<String, List<String>> map = new LinkedHashMap<>();
for (@NotNull String line : lines) {
@NotNull List<String> words = Splitter.on('\t').splitToList(line);
if (!words.isEmpty()) {
String key = words.get(0);
if (key.length() == 0) {
continue;
}
if (patternKey) {
key = StringEscapeUtils.unescapeJava(key);
String del = DEL_PATTERN.matcher(key).replaceAll("");
if (del.length() != 0) {
key = del;
}
}
map.put(key, words);
}
}
return map;
}
}

View File

@@ -1,14 +1,24 @@
package io.github.linwancen.plugin.show.lang;
import com.intellij.json.psi.JsonArray;
import com.intellij.json.psi.JsonObject;
import com.intellij.json.psi.JsonProperty;
import com.intellij.json.psi.JsonValue;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import io.github.linwancen.plugin.show.bean.SettingsInfo;
import io.github.linwancen.plugin.show.lang.base.BaseLangDoc;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import io.github.linwancen.plugin.show.bean.LineInfo;
import io.github.linwancen.plugin.show.ext.conf.ConfCacheGetUtils;
import io.github.linwancen.plugin.show.ext.conf.TsvLoader;
import io.github.linwancen.plugin.show.lang.base.BaseLangDoc;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class JsonLangDoc extends BaseLangDoc {
public static final JsonLangDoc INSTANCE = new JsonLangDoc();
@@ -37,11 +47,15 @@ public class JsonLangDoc extends BaseLangDoc {
}
@Override
protected @Nullable <T extends SettingsInfo> String refDoc(@NotNull T lineInfo, @NotNull PsiElement ref) {
protected @Nullable String refDoc(@NotNull LineInfo lineInfo, @NotNull PsiElement ref) {
if (!(ref instanceof JsonProperty)) {
return null;
}
@NotNull JsonProperty jsonProperty = (JsonProperty) ref;
@Nullable String dictDoc = dictDoc(lineInfo, jsonProperty);
if (dictDoc != null) {
return dictDoc;
}
@NotNull PsiReference[] references = jsonProperty.getNameElement().getReferences();
for (@NotNull PsiReference reference : references) {
@Nullable PsiElement resolve = null;
@@ -60,4 +74,48 @@ public class JsonLangDoc extends BaseLangDoc {
}
return null;
}
@Nullable
private static String dictDoc(@NotNull LineInfo lineInfo, @NotNull JsonProperty prop) {
@Nullable JsonValue value = prop.getValue();
if (value == null || value instanceof JsonArray || value instanceof JsonObject) {
return null;
}
@NotNull GlobalSearchScope scope = GlobalSearchScope.allScope(lineInfo.project);
String jsonKey = prop.getName();
String jsonValue = value.getText();
// Read the json.path before if needed
return jsonDictDoc(lineInfo, scope, jsonKey, jsonValue);
}
@Nullable
private static String jsonDictDoc(@NotNull LineInfo lineInfo, @NotNull GlobalSearchScope scope, String fileName, String jsonValue) {
@NotNull Collection<VirtualFile> files = FilenameIndex.getVirtualFilesByName(lineInfo.project, fileName + ".tsv", scope);
// one file
if (files.size() < 2) {
for (@NotNull VirtualFile file : files) {
@NotNull Map<String, List<String>> map = TsvLoader.buildMap(file, false);
List<String> list = map.get(jsonValue);
if (list != null && list.size() > 1) {
return list.get(1);
}
}
return null;
}
// multi file
@NotNull Map<VirtualFile, Map<String, List<String>>> fileMap = new ConcurrentHashMap<>();
for (@NotNull VirtualFile file : files) {
@NotNull Map<String, List<String>> map = TsvLoader.buildMap(file, false);
fileMap.put(file, map);
}
@NotNull String path = lineInfo.file.getPath();
@NotNull SortedMap<String, Map<String, List<String>>> treeMap = ConfCacheGetUtils.filterPath(fileMap, path);
for (@NotNull Map.Entry<String, Map<String, List<String>>> entry : treeMap.entrySet()) {
List<String> list = entry.getValue().get(jsonValue);
if (list != null && list.size() > 1) {
return list.get(1);
}
}
return null;
}
}

View File

@@ -5,10 +5,9 @@ import com.intellij.psi.PsiElement;
import com.intellij.sql.psi.SqlLanguage;
import com.intellij.sql.psi.SqlReferenceExpression;
import com.intellij.util.containers.JBIterable;
import io.github.linwancen.plugin.show.bean.SettingsInfo;
import io.github.linwancen.plugin.show.bean.LineInfo;
import io.github.linwancen.plugin.show.lang.base.BaseLangDoc;
import io.github.linwancen.plugin.show.lang.base.DocSkip;
import io.github.linwancen.plugin.show.bean.LineInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,8 +31,8 @@ public class SqlLangDoc extends BaseLangDoc {
@Override
protected @Nullable <T extends SettingsInfo> String refElementDoc(@NotNull T lineInfo,
@NotNull PsiElement ref) {
protected @Nullable String refElementDoc(@NotNull LineInfo lineInfo,
@NotNull PsiElement ref) {
JBIterable<DbElement> relatedDbElements;
Class<?> clazz;
try {
@@ -48,7 +47,7 @@ public class SqlLangDoc extends BaseLangDoc {
}
}
try {
Method method = clazz.getMethod("findRelatedDbElements", PsiElement.class, boolean.class);
@NotNull Method method = clazz.getMethod("findRelatedDbElements", PsiElement.class, boolean.class);
//noinspection unchecked
relatedDbElements = (JBIterable<DbElement>) method.invoke(null, ref, false);
} catch (Throwable e) {

View File

@@ -116,8 +116,8 @@ public abstract class BaseLangDoc extends EditorLinePainter {
* Override like SQL
*/
@Nullable
protected <T extends SettingsInfo> String refElementDoc(@NotNull T lineInfo,
@NotNull PsiElement refElement) {
protected String refElementDoc(@NotNull LineInfo lineInfo,
@NotNull PsiElement refElement) {
@Nullable String refDoc = refDoc(lineInfo, refElement);
if (refDoc != null && !DocSkip.skipDoc(lineInfo.appSettings, lineInfo.projectSettings, refDoc)) {
return refDoc;
@@ -129,7 +129,7 @@ public abstract class BaseLangDoc extends EditorLinePainter {
* Override like Java/Json
*/
@Nullable
protected <T extends SettingsInfo> String refDoc(@NotNull T lineInfo, @NotNull PsiElement ref) {
protected String refDoc(@NotNull LineInfo lineInfo, @NotNull PsiElement ref) {
// kotlin ref.getReference() == null but ref.getReferences().length == 2
@NotNull PsiReference[] references = ref.getReferences();
if (references.length < 1) {