1.4 Find element right to left for end-of-line comment | 从右往左查找行末注释对象
This commit is contained in:
@@ -6,16 +6,11 @@ import com.intellij.openapi.editor.EditorLinePainter;
|
||||
import com.intellij.openapi.editor.LineExtensionInfo;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import io.github.linwancen.plugin.comment.settings.AppSettingsState;
|
||||
import io.github.linwancen.plugin.comment.utils.CommentFactory;
|
||||
import io.github.linwancen.plugin.comment.utils.PsiDocCommentUtils;
|
||||
import io.github.linwancen.plugin.comment.utils.PsiMethodCommentFactory;
|
||||
import io.github.linwancen.plugin.comment.utils.SkipUtils;
|
||||
import io.github.linwancen.plugin.comment.utils.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -35,7 +30,7 @@ public class LineEnd extends EditorLinePainter {
|
||||
return null;
|
||||
}
|
||||
FileViewProvider viewProvider = PsiManager.getInstance(project).findViewProvider(file);
|
||||
PsiElement psiElement = psiElementFrom(viewProvider, lineNumber);
|
||||
PsiElement psiElement = resolveElementFrom(viewProvider, lineNumber);
|
||||
PsiDocComment docComment = psiDocCommentFrom(psiElement);
|
||||
String comment = PsiDocCommentUtils.getCommentText(docComment);
|
||||
if (comment == null) {
|
||||
@@ -45,6 +40,25 @@ public class LineEnd extends EditorLinePainter {
|
||||
return Collections.singletonList(info);
|
||||
}
|
||||
|
||||
private static @Nullable PsiElement resolveElementFrom(FileViewProvider viewProvider, int lineNumber) {
|
||||
if (viewProvider == null || !viewProvider.hasLanguage(JavaLanguage.INSTANCE)) {
|
||||
return null;
|
||||
}
|
||||
Document document = viewProvider.getDocument();
|
||||
if (document == null) {
|
||||
return null;
|
||||
}
|
||||
if (document.getLineCount() < lineNumber) {
|
||||
return null;
|
||||
}
|
||||
int startOffset = document.getLineStartOffset(lineNumber);
|
||||
int endOffset = document.getLineEndOffset(lineNumber);
|
||||
if (AppSettingsState.getInstance().findElementRightToLeft) {
|
||||
return ResolveElementRightToLeftUtils.resolveElement(viewProvider, startOffset, endOffset);
|
||||
}
|
||||
return ResolveElementLeftToRightUtils.resolveElement(viewProvider, document, startOffset, endOffset);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiDocComment psiDocCommentFrom(PsiElement psiElement) {
|
||||
if (psiElement == null) {
|
||||
@@ -73,135 +87,4 @@ public class LineEnd extends EditorLinePainter {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static final String[] KEYS = {
|
||||
"=",
|
||||
};
|
||||
|
||||
private static @Nullable PsiElement psiElementFrom(FileViewProvider viewProvider, int lineNumber) {
|
||||
if (viewProvider == null || !viewProvider.hasLanguage(JavaLanguage.INSTANCE)) {
|
||||
return null;
|
||||
}
|
||||
Document document = viewProvider.getDocument();
|
||||
if (document == null) {
|
||||
return null;
|
||||
}
|
||||
if (document.getLineCount() < lineNumber) {
|
||||
return null;
|
||||
}
|
||||
int startOffset = document.getLineStartOffset(lineNumber);
|
||||
int endOffset = document.getLineEndOffset(lineNumber);
|
||||
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 = psiIdentifier(endOffset, element);
|
||||
if (psiIdentifier == null) {
|
||||
return null;
|
||||
}
|
||||
return parentElementOf(psiIdentifier, startOffset, endOffset);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiIdentifier psiIdentifier(int endOffset, PsiElement element) {
|
||||
if (element == null) {
|
||||
return null;
|
||||
}
|
||||
while (!(element instanceof PsiIdentifier)) {
|
||||
element = PsiTreeUtil.nextVisibleLeaf(element);
|
||||
if (element == null) {
|
||||
return null;
|
||||
}
|
||||
if (element.getTextRange().getEndOffset() > endOffset) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return (PsiIdentifier) element;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement parentElementOf(PsiElement psiIdentifier, int startOffset, int endOffset) {
|
||||
// method call
|
||||
PsiMethodCallExpression call =
|
||||
PsiTreeUtil.getParentOfType(psiIdentifier, PsiMethodCallExpression.class, false, startOffset);
|
||||
if (call != null) {
|
||||
// skip double comment when method call in new line:
|
||||
// someObject // someMethodComment
|
||||
// .someMethod(); // someMethodComment
|
||||
if ((call.getNode().getStartOffset() + call.getNode().getTextLength()) > endOffset) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return call.resolveMethod();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// new
|
||||
PsiElement newPsiElement = newMethodOrClass(psiIdentifier, startOffset);
|
||||
if (newPsiElement != null) {
|
||||
return newPsiElement;
|
||||
}
|
||||
// ::/class/field
|
||||
PsiReference psiReference = parentPsiReference(psiIdentifier, endOffset);
|
||||
if (psiReference != null) {
|
||||
return psiReference.resolve();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement newMethodOrClass(PsiElement element, int startOffset) {
|
||||
// new and Class should same line
|
||||
PsiNewExpression newExp = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class, false, startOffset);
|
||||
if (newExp != null) {
|
||||
PsiMethod psiMethod = newExp.resolveMethod();
|
||||
if (psiMethod != null) {
|
||||
return psiMethod;
|
||||
}
|
||||
PsiJavaCodeReferenceElement classReference = newExp.getClassReference();
|
||||
if (classReference != null) {
|
||||
return classReference.resolve();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiReference parentPsiReference(PsiElement element, int endOffset) {
|
||||
PsiElement parent;
|
||||
while ((parent = element.getParent()) instanceof PsiReference) {
|
||||
if (parent.getTextRange().getEndOffset() > endOffset) {
|
||||
break;
|
||||
}
|
||||
element = parent;
|
||||
}
|
||||
if (element instanceof PsiReference) {
|
||||
return (PsiReference) element;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,12 +15,13 @@ public class AppSettingsComponent extends AbstractSettingsComponent {
|
||||
private final JBCheckBox showTreeComment = new JBCheckBox("Show tree comment ");
|
||||
private final JBCheckBox showLineEndComment = new JBCheckBox("Show line end comment ");
|
||||
private final ColorPanel lineEndColor = new ColorPanel();
|
||||
private final JBCheckBox findElementRightToLeft = new JBCheckBox("Find element right to left");
|
||||
|
||||
public AppSettingsComponent() {
|
||||
myMainPanel = FormBuilder.createFormBuilder()
|
||||
.addComponent(showPanel(), 1)
|
||||
.addComponent(colorPanel(), 1)
|
||||
.addComponent(commonLineEndFilter(FormBuilder.createFormBuilder()), 1)
|
||||
.addComponent(lineEndFilterPanel(), 1)
|
||||
.addComponentFillVertically(new JPanel(), 0)
|
||||
.getPanel();
|
||||
}
|
||||
@@ -44,6 +45,14 @@ public class AppSettingsComponent extends AbstractSettingsComponent {
|
||||
return color;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected JPanel lineEndFilterPanel() {
|
||||
FormBuilder formBuilder = FormBuilder.createFormBuilder()
|
||||
.addComponent(findElementRightToLeft)
|
||||
.addSeparator();
|
||||
return commonLineEndFilter(formBuilder);
|
||||
}
|
||||
|
||||
public JPanel getPanel() {
|
||||
return myMainPanel;
|
||||
}
|
||||
@@ -76,4 +85,12 @@ public class AppSettingsComponent extends AbstractSettingsComponent {
|
||||
public void setLineEndColor(Color color) {
|
||||
lineEndColor.setSelectedColor(color);
|
||||
}
|
||||
|
||||
public boolean getFindElementRightToLeft() {
|
||||
return findElementRightToLeft.isSelected();
|
||||
}
|
||||
|
||||
public void setFindElementRightToLeft(boolean newStatus) {
|
||||
findElementRightToLeft.setSelected(newStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ public class AppSettingsConfigurable implements Configurable {
|
||||
} else {
|
||||
modified |= !mySettingsComponent.getLineEndColor().equals(settings.lineEndColorBright);
|
||||
}
|
||||
modified |= mySettingsComponent.getFindElementRightToLeft() != settings.findElementRightToLeft;
|
||||
modified |= !mySettingsComponent.getLineEndInclude().equals(settings.lineEndInclude);
|
||||
modified |= !mySettingsComponent.getLineEndExclude().equals(settings.lineEndExclude);
|
||||
return modified;
|
||||
@@ -57,6 +58,7 @@ public class AppSettingsConfigurable implements Configurable {
|
||||
}
|
||||
JBColor jbColor = new JBColor(settings.lineEndColorBright, settings.lineEndColorDark);
|
||||
settings.lineEndTextAttr.setForegroundColor(jbColor);
|
||||
settings.findElementRightToLeft = mySettingsComponent.getFindElementRightToLeft();
|
||||
settings.lineEndInclude = mySettingsComponent.getLineEndInclude();
|
||||
settings.lineEndExclude = mySettingsComponent.getLineEndExclude();
|
||||
settings.lineEndIncludeArray = SplitUtils.split(settings.lineEndInclude);
|
||||
@@ -73,6 +75,7 @@ public class AppSettingsConfigurable implements Configurable {
|
||||
} else {
|
||||
mySettingsComponent.setLineEndColor(settings.lineEndColorBright);
|
||||
}
|
||||
mySettingsComponent.setFindElementRightToLeft(settings.findElementRightToLeft);
|
||||
mySettingsComponent.setLineEndInclude(settings.lineEndInclude);
|
||||
mySettingsComponent.setLineEndExclude(settings.lineEndExclude);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ public class AppSettingsState implements PersistentStateComponent<AppSettingsSta
|
||||
public final TextAttributes lineEndTextAttr = new TextAttributes(new JBColor(lineEndColorBright, lineEndColorDark),
|
||||
null, null, null, Font.ITALIC);
|
||||
|
||||
public boolean findElementRightToLeft = true;
|
||||
public String lineEndInclude = "";
|
||||
public String lineEndExclude = "java.";
|
||||
public String[] lineEndIncludeArray = {};
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package io.github.linwancen.plugin.comment.utils;
|
||||
|
||||
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.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ResolveElementLeftToRightUtils {
|
||||
|
||||
private ResolveElementLeftToRightUtils() {}
|
||||
|
||||
protected static final String[] KEYS = {
|
||||
"=",
|
||||
};
|
||||
|
||||
@Nullable
|
||||
public static PsiElement resolveElement(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 = psiIdentifier(endOffset, element);
|
||||
if (psiIdentifier == null) {
|
||||
return null;
|
||||
}
|
||||
return ResolveElementUtils.resolveElementOf(psiIdentifier, psiIdentifier, startOffset, endOffset);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiIdentifier psiIdentifier(int endOffset, PsiElement element) {
|
||||
if (element == null) {
|
||||
return null;
|
||||
}
|
||||
while (!(element instanceof PsiIdentifier)) {
|
||||
element = PsiTreeUtil.nextVisibleLeaf(element);
|
||||
if (element == null) {
|
||||
return null;
|
||||
}
|
||||
if (element.getTextRange().getEndOffset() > endOffset) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return (PsiIdentifier) element;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package io.github.linwancen.plugin.comment.utils;
|
||||
|
||||
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.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ResolveElementRightToLeftUtils {
|
||||
|
||||
private ResolveElementRightToLeftUtils() {}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement resolveElement(FileViewProvider viewProvider, int startOffset, int endOffset) {
|
||||
if (startOffset == endOffset) {
|
||||
return null;
|
||||
}
|
||||
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;
|
||||
}
|
||||
return ResolveElementUtils.resolveElementOf(element, identifier, startOffset, endOffset);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package io.github.linwancen.plugin.comment.utils;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ResolveElementUtils {
|
||||
|
||||
private ResolveElementUtils() {}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement resolveElementOf(PsiElement element, PsiElement psiIdentifier,
|
||||
int startOffset, int endOffset) {
|
||||
// method call
|
||||
PsiMethodCallExpression call =
|
||||
PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class, false, startOffset);
|
||||
if (call != null) {
|
||||
// skip double comment when method call in new line:
|
||||
// someObject // someMethodComment
|
||||
// .someMethod(); // someMethodComment
|
||||
if ((call.getNode().getStartOffset() + call.getNode().getTextLength()) > endOffset) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return call.resolveMethod();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// new
|
||||
PsiElement newPsiElement = newMethodOrClass(element, startOffset);
|
||||
if (newPsiElement != null) {
|
||||
return newPsiElement;
|
||||
}
|
||||
// ::/class/field
|
||||
PsiReference psiReference = parentPsiReference(psiIdentifier, endOffset);
|
||||
if (psiReference != null) {
|
||||
return psiReference.resolve();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement newMethodOrClass(PsiElement element, int startOffset) {
|
||||
// new and Class should same line
|
||||
PsiNewExpression newExp = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class, false, startOffset);
|
||||
if (newExp != null) {
|
||||
PsiMethod psiMethod = newExp.resolveMethod();
|
||||
if (psiMethod != null) {
|
||||
return psiMethod;
|
||||
}
|
||||
PsiJavaCodeReferenceElement classReference = newExp.getClassReference();
|
||||
if (classReference != null) {
|
||||
return classReference.resolve();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiReference parentPsiReference(PsiElement element, int endOffset) {
|
||||
PsiElement parent;
|
||||
while ((parent = element.getParent()) instanceof PsiReference) {
|
||||
if (parent.getTextRange().getEndOffset() > endOffset) {
|
||||
break;
|
||||
}
|
||||
element = parent;
|
||||
}
|
||||
if (element instanceof PsiReference) {
|
||||
return (PsiReference) element;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user