1.5 Support find next when not comment | 支持没有注释时查找下一个对象

This commit is contained in:
林万程
2022-02-26 03:10:43 +08:00
parent 35e2548967
commit 89a0c1cd60
32 changed files with 495 additions and 252 deletions

View File

@@ -0,0 +1,68 @@
package io.github.linwancen.plugin.show.line;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiIdentifier;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
public class LineDocLeftToRightUtils {
private LineDocLeftToRightUtils() {}
static final String[] KEYS = {
"=",
};
@Nullable
public static PsiDocComment leftDoc(FileViewProvider viewProvider, Document document,
int startOffset, int endOffset) {
String text = document.getText(new TextRange(startOffset, endOffset));
int offset = 0;
for (String s : KEYS) {
int i = text.indexOf(s);
if (i > 0) {
offset += (i + s.length());
break;
}
}
text = text.substring(offset);
boolean startWithSymbol = false;
char[] chars = text.toCharArray();
// skip symbol and space
for (char c : chars) {
if (Character.isLetter(c)) {
break;
}
if (!Character.isSpaceChar(c)) {
startWithSymbol = true;
}
offset++;
}
offset += startOffset;
if (startWithSymbol) {
startOffset = 0;
}
PsiElement element = viewProvider.findElementAt(offset, JavaLanguage.INSTANCE);
PsiIdentifier psiIdentifier = leftIdentifier(element, endOffset);
return LineDocUtils.elementDoc(psiIdentifier, psiIdentifier, startOffset, endOffset);
}
@Nullable
private static PsiIdentifier leftIdentifier(PsiElement element, int endOffset) {
if (element == null) {
return null;
}
while (!(element instanceof PsiIdentifier)) {
element = PsiTreeUtil.nextVisibleLeaf(element);
if (element == null || element.getTextRange().getEndOffset() > endOffset) {
return null;
}
}
return (PsiIdentifier) element;
}
}

View File

@@ -0,0 +1,35 @@
package io.github.linwancen.plugin.show.line;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiIdentifier;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
public class LineDocRightToLeftUtils {
private LineDocRightToLeftUtils() {}
@Nullable
public static PsiDocComment rightDoc(FileViewProvider viewProvider, int startOffset, int endOffset) {
// End is always white, can not -1 because @see class.name need it
PsiElement element = viewProvider.findElementAt(endOffset, JavaLanguage.INSTANCE);
if (element == null) {
return null;
}
PsiElement identifier;
while (!((identifier = PsiTreeUtil.prevVisibleLeaf(element)) instanceof PsiIdentifier)) {
if (identifier == null || identifier.getTextRange().getStartOffset() < startOffset) {
break;
}
element = identifier;
}
// if in prev line, set it null.
if (identifier != null && identifier.getTextRange().getStartOffset() < startOffset) {
identifier = null;
}
return LineDocUtils.elementDoc(element, identifier, startOffset, endOffset);
}
}

View File

@@ -0,0 +1,143 @@
package io.github.linwancen.plugin.show.line;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
class LineDocUtils {
private LineDocUtils() {}
@Nullable
static PsiDocComment elementDoc(PsiElement element, PsiElement psiIdentifier,
int startOffset, int endOffset) {
if (element != null) {
PsiDocComment executableDoc = parentMethodDoc(element, startOffset, endOffset);
if (executableDoc != null) {
return executableDoc;
}
PsiDocComment newDoc = parentNewDoc(element, startOffset);
if (newDoc != null) {
return newDoc;
}
PsiDocComment docRefDoc = docRefDoc(element);
if (docRefDoc != null) {
return docRefDoc;
}
}
return refDoc(psiIdentifier, endOffset);
}
@Nullable
private static PsiDocComment parentMethodDoc(PsiElement element, int startOffset, int endOffset) {
// method call
PsiMethodCallExpression call =
PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class, false, startOffset);
if (call == null) {
return null;
}
if ((call.getNode().getStartOffset() + call.getNode().getTextLength()) > endOffset) {
return null;
}
try {
PsiDocComment methodComment = SkipDocUtils.methodDoc(call.resolveMethod());
if (methodComment != null) {
return methodComment;
}
} catch (Exception ignored) {
// ignored
}
return null;
}
@Nullable
private static PsiDocComment parentNewDoc(PsiElement element, int startOffset) {
// new and Class should same line, so not need if endOffset
PsiNewExpression newExp = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class, false, startOffset);
if (newExp == null) {
return null;
}
PsiDocComment methodComment = SkipDocUtils.methodDoc(newExp.resolveMethod());
if (methodComment != null) {
return methodComment;
}
PsiJavaCodeReferenceElement classReference = newExp.getClassReference();
return javaCodeDoc(classReference);
}
/**
* ::/class/field
*/
@Nullable
private static PsiDocComment refDoc(PsiElement element, int endOffset) {
if (element == null) {
return null;
}
// while for xx.xx.xx... when left to right, only once when right to left
PsiElement parent;
while ((parent = element.getParent()) instanceof PsiReference) {
if (parent.getTextRange().getEndOffset() > endOffset) {
break;
}
element = parent;
}
if (element instanceof PsiReference) {
PsiElement resolve = ((PsiReference) element).resolve();
if (resolve instanceof PsiDocCommentOwner) {
return SkipDocUtils.refDoc(((PsiDocCommentOwner) resolve));
}
}
// for right to left field
if (parent instanceof PsiDocCommentOwner) {
return SkipDocUtils.refDoc(((PsiDocCommentOwner) parent));
}
// for right to left for
if (parent instanceof PsiForeachStatement) {
PsiParameter iterationParameter = ((PsiForeachStatement) parent).getIterationParameter();
PsiTypeElement typeElement = iterationParameter.getTypeElement();
if (typeElement == null) {
return null;
}
PsiJavaCodeReferenceElement ref = typeElement.getInnermostComponentReferenceElement();
return javaCodeDoc(ref);
}
return null;
}
@Nullable
private static PsiDocComment javaCodeDoc(PsiJavaCodeReferenceElement ref) {
if (ref == null) {
return null;
}
PsiElement resolve = ref.resolve();
if (resolve instanceof PsiDocCommentOwner) {
return SkipDocUtils.refDoc(((PsiDocCommentOwner) resolve));
}
return null;
}
@Nullable
private static PsiDocComment docRefDoc(PsiElement element) {
PsiElement parent = element.getParent();
if (parent instanceof PsiDocMethodOrFieldRef) {
element = parent;
}
if (element instanceof PsiDocMethodOrFieldRef) {
PsiReference reference = element.getReference();
if (reference == null) {
return null;
}
PsiElement resolve = reference.resolve();
if (resolve instanceof PsiMethod) {
return SkipDocUtils.methodDoc(((PsiMethod) resolve));
}
if (resolve instanceof PsiDocCommentOwner) {
return SkipDocUtils.refDoc(((PsiDocCommentOwner) resolve));
}
}
return null;
}
}

View File

@@ -0,0 +1,37 @@
package io.github.linwancen.plugin.show.line;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDocCommentOwner;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.javadoc.PsiDocComment;
import io.github.linwancen.plugin.show.doc.DocUtils;
import org.jetbrains.annotations.Nullable;
class SkipDocUtils {
private SkipDocUtils() {}
static PsiDocComment methodDoc(@Nullable PsiMethod psiMethod) {
if (skip(psiMethod)) {
return null;
}
return DocUtils.methodDoc(psiMethod);
}
static PsiDocComment refDoc(@Nullable PsiDocCommentOwner docOwner) {
if (skip(docOwner)) {
return null;
}
return DocUtils.srcOrByteCodeDoc(docOwner);
}
static boolean skip(@Nullable PsiDocCommentOwner docOwner) {
if (docOwner == null) {
return true;
}
if (docOwner instanceof PsiClass) {
return SkipUtils.skip((PsiClass) docOwner, docOwner.getProject());
}
return SkipUtils.skip(docOwner.getContainingClass(), docOwner.getProject());
}
}

View File

@@ -0,0 +1,54 @@
package io.github.linwancen.plugin.show.line;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import io.github.linwancen.plugin.show.settings.AppSettingsState;
import io.github.linwancen.plugin.show.settings.ProjectSettingsState;
class SkipUtils {
private SkipUtils() {}
static boolean skip(PsiClass psiClass, Project project) {
if (psiClass == null) {
return true;
}
String name = psiClass.getQualifiedName();
if (name == null) {
return true;
}
ProjectSettingsState projectSettings = ProjectSettingsState.getInstance(project);
AppSettingsState appSettings = AppSettingsState.getInstance();
if (projectSettings.globalFilterEffective
&& skipName(name, appSettings.lineEndIncludeArray, appSettings.lineEndExcludeArray)) {
return true;
}
if (projectSettings.projectFilterEffective) {
return skipName(name, projectSettings.lineEndIncludeArray, projectSettings.lineEndExcludeArray);
}
return false;
}
static boolean skipName(String name, String[] includeArray, String[] excludeArray) {
if (exclude(name, excludeArray)) {
return true;
}
return !include(name, includeArray);
}
static boolean include(String name, String[] lineEndIncludeArray) {
if (lineEndIncludeArray.length == 0) {
return true;
}
return exclude(name, lineEndIncludeArray);
}
static boolean exclude(String name, String[] projectLineEndExcludeArray) {
for (String s : projectLineEndExcludeArray) {
if (name.startsWith(s)) {
return true;
}
}
return false;
}
}