From dec8cf172c10538387b3b4ef164e0ac61005950c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9E=97=E4=B8=87=E7=A8=8B?= <1498425439@qq.com>
Date: Fri, 11 Feb 2022 00:23:01 +0800
Subject: [PATCH] 1.0.0
---
.gitignore | 9 +
.idea/runConfigurations/buildPlugin.xml | 21 ++
.idea/runConfigurations/runIde.xml | 21 ++
README.md | 10 +
build.gradle | 50 +++++
gradle.properties | 1 +
settings.gradle | 2 +
.../linwancen/plugin/comment/LineEnd.java | 187 ++++++++++++++++++
.../github/linwancen/plugin/comment/Tree.java | 105 ++++++++++
.../settings/AppSettingsComponent.java | 52 +++++
.../settings/AppSettingsConfigurable.java | 58 ++++++
.../comment/settings/AppSettingsState.java | 34 ++++
.../plugin/comment/utils/CommentFactory.java | 35 ++++
.../comment/utils/PsiDocCommentUtils.java | 52 +++++
.../utils/PsiMethodCommentFactory.java | 71 +++++++
.../utils/PsiPackageCommentFactory.java | 59 ++++++
.../plugin/comment/utils/SkipUtils.java | 16 ++
src/main/resources/META-INF/plugin.xml | 37 ++++
18 files changed, 820 insertions(+)
create mode 100644 .gitignore
create mode 100644 .idea/runConfigurations/buildPlugin.xml
create mode 100644 .idea/runConfigurations/runIde.xml
create mode 100644 build.gradle
create mode 100644 gradle.properties
create mode 100644 settings.gradle
create mode 100644 src/main/java/io/github/linwancen/plugin/comment/LineEnd.java
create mode 100644 src/main/java/io/github/linwancen/plugin/comment/Tree.java
create mode 100644 src/main/java/io/github/linwancen/plugin/comment/settings/AppSettingsComponent.java
create mode 100644 src/main/java/io/github/linwancen/plugin/comment/settings/AppSettingsConfigurable.java
create mode 100644 src/main/java/io/github/linwancen/plugin/comment/settings/AppSettingsState.java
create mode 100644 src/main/java/io/github/linwancen/plugin/comment/utils/CommentFactory.java
create mode 100644 src/main/java/io/github/linwancen/plugin/comment/utils/PsiDocCommentUtils.java
create mode 100644 src/main/java/io/github/linwancen/plugin/comment/utils/PsiMethodCommentFactory.java
create mode 100644 src/main/java/io/github/linwancen/plugin/comment/utils/PsiPackageCommentFactory.java
create mode 100644 src/main/java/io/github/linwancen/plugin/comment/utils/SkipUtils.java
create mode 100644 src/main/resources/META-INF/plugin.xml
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ba21272
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+
+**/.idea/*
+!**/.idea/runConfigurations
+!**/.idea/scopes
+
+.gradle
+build
+
+.qodana
\ No newline at end of file
diff --git a/.idea/runConfigurations/buildPlugin.xml b/.idea/runConfigurations/buildPlugin.xml
new file mode 100644
index 0000000..b407f2e
--- /dev/null
+++ b/.idea/runConfigurations/buildPlugin.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ false
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/runIde.xml b/.idea/runConfigurations/runIde.xml
new file mode 100644
index 0000000..ac41c3f
--- /dev/null
+++ b/.idea/runConfigurations/runIde.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ false
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index e69de29..40d835a 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1,10 @@
+# Show Comment Plugin
+IDEA 智能注释插件
+
+English Note:
+- Show javadoc comments for calling methods at the end of the line.
+- Show javadoc comments in the Project view Tree structure.
+
+Chinese Note:
+- 在行末显示调用方法的文档注释。
+- 在结构树显示文档注释。
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..fbc21d2
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,50 @@
+plugins {
+ id 'org.jetbrains.intellij' version '1.3.1'
+ id 'java'
+}
+
+group 'io.github.linwancen'
+version '1.0.0.' + (new Date().format('yyyy.MM.dd_HH.mm'))
+
+apply plugin: 'java'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
+ testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
+}
+
+// See https://github.com/JetBrains/gradle-intellij-plugin/
+intellij {
+ version = ideaVersion
+ plugins = ['java']
+}
+
+tasks.withType(JavaCompile) {
+ options.encoding = 'UTF-8'
+}
+
+tasks.withType(Javadoc) {
+ options.encoding = 'UTF-8'
+}
+
+patchPluginXml {
+ // The performance of 2019.3 has been greatly improved.
+ // change plugins without restarting the IDE in 2020.1.
+ sinceBuild = '201.1'
+ untilBuild = ''
+ changeNotes = """
+ Code optimization | 代码优化
+ """
+}
+
+test {
+ useJUnitPlatform()
+}
+
+publishPlugin {
+ token = System.getenv("PUBLISH_TOKEN")
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..813fac9
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1 @@
+ideaVersion=2020.1
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..d569dbf
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,2 @@
+rootProject.name = 'show-comment'
+
diff --git a/src/main/java/io/github/linwancen/plugin/comment/LineEnd.java b/src/main/java/io/github/linwancen/plugin/comment/LineEnd.java
new file mode 100644
index 0000000..4e9c458
--- /dev/null
+++ b/src/main/java/io/github/linwancen/plugin/comment/LineEnd.java
@@ -0,0 +1,187 @@
+package io.github.linwancen.plugin.comment;
+
+import com.intellij.lang.java.JavaLanguage;
+import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.EditorLinePainter;
+import com.intellij.openapi.editor.LineExtensionInfo;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.markup.TextAttributes;
+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.impl.source.PsiJavaCodeReferenceElementImpl;
+import com.intellij.psi.javadoc.PsiDocComment;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.ui.Gray;
+import com.intellij.ui.JBColor;
+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 org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.*;
+import java.util.Collection;
+import java.util.Collections;
+
+public class LineEnd extends EditorLinePainter {
+ @Override
+ public @Nullable Collection getLineExtensions(@NotNull Project project,
+ @NotNull VirtualFile file, int lineNumber) {
+ if (!AppSettingsState.getInstance().showLineEndComment) {
+ return null;
+ }
+ if (DumbService.isDumb(project)) {
+ return null;
+ }
+ FileViewProvider viewProvider = PsiManager.getInstance(project).findViewProvider(file);
+ PsiElement psiElement = psiElementFrom(viewProvider, lineNumber);
+ PsiDocComment docComment = psiDocCommentFrom(psiElement);
+ String comment = PsiDocCommentUtils.getCommentText(docComment);
+ if (comment == null) {
+ return null;
+ }
+ LineExtensionInfo info = new LineExtensionInfo(" //" + comment, getNormalAttributes());
+ return Collections.singletonList(info);
+ }
+
+ @Nullable
+ private PsiDocComment psiDocCommentFrom(PsiElement psiElement) {
+ if (psiElement == null) {
+ return null;
+ }
+ if (psiElement instanceof PsiClass) {
+ PsiClass psiClass = (PsiClass) psiElement;
+ if (SkipUtils.skip(psiClass)) {
+ return null;
+ }
+ return CommentFactory.fromSrcOrByteCode(psiClass);
+ }
+ if (psiElement instanceof PsiMethod) {
+ PsiMethod psiMethod = (PsiMethod) psiElement;
+ if (SkipUtils.skip(psiMethod.getContainingClass())) {
+ return null;
+ }
+ return PsiMethodCommentFactory.from(psiMethod);
+ }
+ return null;
+ }
+
+ protected static final String[] KEYS = {
+ "if",
+ "for",
+ "new",
+ "=",
+ "return",
+ };
+
+ 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);
+ if (!(element instanceof PsiIdentifier)) {
+ return null;
+ }
+ return parentElementOf(element, startOffset, endOffset);
+ }
+
+ @Nullable
+ private static PsiElement parentElementOf(PsiElement element, 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
+ 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();
+ }
+ }
+ // ::
+ PsiMethodReferenceExpression ref =
+ PsiTreeUtil.getParentOfType(element, PsiMethodReferenceExpression.class, false, startOffset);
+ if (ref != null) {
+ return ref.resolve();
+ }
+ // SomeClass // SomeClassComment
+ PsiJavaCodeReferenceElementImpl code =
+ PsiTreeUtil.getParentOfType(element, PsiJavaCodeReferenceElementImpl.class, false, startOffset);
+ if (code != null) {
+ return code.resolve();
+ }
+ return null;
+ }
+
+ private static TextAttributes getNormalAttributes() {
+ EditorColorsManager colorsManager = EditorColorsManager.getInstance();
+ TextAttributes attributes = colorsManager.getGlobalScheme()
+ .getAttributes(DefaultLanguageHighlighterColors.LINE_COMMENT);
+ if (attributes == null || attributes.getForegroundColor() == null) {
+ JBColor jbColor = new JBColor(() -> Gray._183);
+ return new TextAttributes(jbColor, null, null, null, Font.ITALIC);
+ } else {
+ // Sometimes it becomes the same color as the end of the line char, so use italic to distinguish
+ attributes.setFontType(Font.ITALIC);
+ }
+ return attributes;
+ }
+}
diff --git a/src/main/java/io/github/linwancen/plugin/comment/Tree.java b/src/main/java/io/github/linwancen/plugin/comment/Tree.java
new file mode 100644
index 0000000..eb33199
--- /dev/null
+++ b/src/main/java/io/github/linwancen/plugin/comment/Tree.java
@@ -0,0 +1,105 @@
+package io.github.linwancen.plugin.comment;
+
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.ide.projectView.ProjectViewNode;
+import com.intellij.ide.projectView.ProjectViewNodeDecorator;
+import com.intellij.ide.projectView.impl.nodes.*;
+import com.intellij.ide.util.treeView.PresentableNodeDescriptor.ColoredFragment;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packageDependencies.ui.PackageDependenciesNode;
+import com.intellij.psi.*;
+import com.intellij.psi.javadoc.PsiDocComment;
+import com.intellij.ui.ColoredTreeCellRenderer;
+import com.intellij.ui.SimpleTextAttributes;
+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.PsiPackageCommentFactory;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+public class Tree implements ProjectViewNodeDecorator {
+
+ @Override
+ public void decorate(ProjectViewNode node, PresentationData data) {
+ if (!AppSettingsState.getInstance().showTreeComment) {
+ return;
+ }
+ Project project = node.getProject();
+ if (project == null) {
+ return;
+ }
+ if (DumbService.isDumb(project)) {
+ return;
+ }
+
+ PsiDocComment docComment = psiDocCommentOf(node, project);
+ if (docComment == null) {
+ return;
+ }
+
+ String commentText = PsiDocCommentUtils.getCommentText(docComment);
+ if (commentText == null) {
+ return;
+ }
+ List coloredText = data.getColoredText();
+ if (coloredText.isEmpty()) {
+ data.addText(data.getPresentableText(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ }
+ data.addText(commentText, SimpleTextAttributes.GRAY_ATTRIBUTES);
+ }
+
+ @Nullable
+ private PsiDocComment psiDocCommentOf(ProjectViewNode> node, Project project) {
+ if (node instanceof PsiFileNode) {
+ PsiFile psiFile = ((PsiFileNode) node).getValue();
+ return CommentFactory.from(psiFile);
+ }
+ if (node instanceof PsiDirectoryNode) {
+ PsiDirectory psiDirectory = ((PsiDirectoryNode) node).getValue();
+ return PsiPackageCommentFactory.from(psiDirectory);
+ }
+
+ if (node instanceof PsiMethodNode) {
+ // On Show Members
+ PsiMethod psiMethod = ((PsiMethodNode) node).getValue();
+ return PsiMethodCommentFactory.from(psiMethod);
+ }
+ if (node instanceof PsiFieldNode) {
+ // On Show Members
+ PsiField psiField = ((PsiFieldNode) node).getValue();
+ return psiField.getDocComment();
+ }
+
+ if (node instanceof ClassTreeNode) {
+ // On Packages View, Project Files View, Show Members
+ PsiClass psiClass = ((ClassTreeNode) node).getValue();
+ return psiClass.getDocComment();
+ }
+ if (node instanceof PackageElementNode) {
+ // On Packages View
+ PsiPackage psiPackage = ((PackageElementNode) node).getValue().getPackage();
+ return PsiPackageCommentFactory.from(psiPackage);
+ }
+
+ // On Packages View, Project Files View
+ VirtualFile virtualFile = node.getVirtualFile();
+ if (virtualFile == null || !virtualFile.isDirectory()) {
+ return null;
+ }
+ PsiDirectory psiDirectory = PsiManager.getInstance(project).findDirectory(virtualFile);
+ if (psiDirectory == null) {
+ return null;
+ }
+ return PsiPackageCommentFactory.from(psiDirectory);
+ }
+
+ @Override
+ public void decorate(PackageDependenciesNode node, ColoredTreeCellRenderer cellRenderer) {
+ // not need
+ }
+}
diff --git a/src/main/java/io/github/linwancen/plugin/comment/settings/AppSettingsComponent.java b/src/main/java/io/github/linwancen/plugin/comment/settings/AppSettingsComponent.java
new file mode 100644
index 0000000..4d04220
--- /dev/null
+++ b/src/main/java/io/github/linwancen/plugin/comment/settings/AppSettingsComponent.java
@@ -0,0 +1,52 @@
+package io.github.linwancen.plugin.comment.settings;
+
+import com.intellij.ui.IdeBorderFactory;
+import com.intellij.ui.components.JBCheckBox;
+import com.intellij.util.ui.FormBuilder;
+
+import javax.swing.*;
+
+public class AppSettingsComponent {
+
+ private final JPanel myMainPanel;
+ private final JBCheckBox showTreeComment = new JBCheckBox("Show tree comment ");
+ private final JBCheckBox showLineEndComment = new JBCheckBox("Show line end comment ");
+
+ public AppSettingsComponent() {
+ JPanel comment = FormBuilder.createFormBuilder()
+ .addComponent(showTreeComment, 1)
+ .addComponent(showLineEndComment, 1)
+ .addComponentFillVertically(new JPanel(), 0)
+ .getPanel();
+ comment.setBorder(IdeBorderFactory.createTitledBorder("Comment"));
+
+ myMainPanel = FormBuilder.createFormBuilder()
+ .addComponent(comment, 1)
+ .addComponentFillVertically(new JPanel(), 0)
+ .getPanel();
+ }
+
+ public JPanel getPanel() {
+ return myMainPanel;
+ }
+
+ public JComponent getPreferredFocusedComponent() {
+ return showTreeComment;
+ }
+
+ public boolean getShowTreeComment() {
+ return showTreeComment.isSelected();
+ }
+
+ public void setShowTreeComment(boolean newStatus) {
+ showTreeComment.setSelected(newStatus);
+ }
+
+ public boolean getShowLineEndComment() {
+ return showLineEndComment.isSelected();
+ }
+
+ public void setShowLineEndComment(boolean newStatus) {
+ showLineEndComment.setSelected(newStatus);
+ }
+}
diff --git a/src/main/java/io/github/linwancen/plugin/comment/settings/AppSettingsConfigurable.java b/src/main/java/io/github/linwancen/plugin/comment/settings/AppSettingsConfigurable.java
new file mode 100644
index 0000000..4e38743
--- /dev/null
+++ b/src/main/java/io/github/linwancen/plugin/comment/settings/AppSettingsConfigurable.java
@@ -0,0 +1,58 @@
+package io.github.linwancen.plugin.comment.settings;
+
+import com.intellij.openapi.options.Configurable;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public class AppSettingsConfigurable implements Configurable {
+
+ private AppSettingsComponent mySettingsComponent;
+
+ @Nls(capitalization = Nls.Capitalization.Title)
+ @Override
+ public String getDisplayName() {
+ return "Show Comment.";
+ }
+
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return mySettingsComponent.getPreferredFocusedComponent();
+ }
+
+ @Nullable
+ @Override
+ public JComponent createComponent() {
+ mySettingsComponent = new AppSettingsComponent();
+ return mySettingsComponent.getPanel();
+ }
+
+ @Override
+ public boolean isModified() {
+ AppSettingsState settings = AppSettingsState.getInstance();
+ boolean modified = mySettingsComponent.getShowTreeComment() != settings.showTreeComment;
+ modified |= mySettingsComponent.getShowLineEndComment() != settings.showLineEndComment;
+ return modified;
+ }
+
+ @Override
+ public void apply() {
+ AppSettingsState settings = AppSettingsState.getInstance();
+ settings.showTreeComment = mySettingsComponent.getShowTreeComment();
+ settings.showLineEndComment = mySettingsComponent.getShowLineEndComment();
+ }
+
+ @Override
+ public void reset() {
+ AppSettingsState settings = AppSettingsState.getInstance();
+ mySettingsComponent.setShowTreeComment(settings.showTreeComment);
+ mySettingsComponent.setShowLineEndComment(settings.showLineEndComment);
+ }
+
+ @Override
+ public void disposeUIResources() {
+ mySettingsComponent = null;
+ }
+
+}
diff --git a/src/main/java/io/github/linwancen/plugin/comment/settings/AppSettingsState.java b/src/main/java/io/github/linwancen/plugin/comment/settings/AppSettingsState.java
new file mode 100644
index 0000000..bbe15fb
--- /dev/null
+++ b/src/main/java/io/github/linwancen/plugin/comment/settings/AppSettingsState.java
@@ -0,0 +1,34 @@
+package io.github.linwancen.plugin.comment.settings;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.openapi.components.State;
+import com.intellij.openapi.components.Storage;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+@State(
+ name = "io.github.linwancen.plugin.comment.settings.AppSettingsState",
+ storages = @Storage("ShowCommentPlugin.xml")
+)
+public class AppSettingsState implements PersistentStateComponent {
+
+ public boolean showLineEndComment = true;
+ public boolean showTreeComment = true;
+
+ public static AppSettingsState getInstance() {
+ return ApplicationManager.getApplication().getService(AppSettingsState.class);
+ }
+
+ @Nullable
+ @Override
+ public AppSettingsState getState() {
+ return this;
+ }
+
+ @Override
+ public void loadState(@NotNull AppSettingsState state) {
+ XmlSerializerUtil.copyBean(state, this);
+ }
+}
diff --git a/src/main/java/io/github/linwancen/plugin/comment/utils/CommentFactory.java b/src/main/java/io/github/linwancen/plugin/comment/utils/CommentFactory.java
new file mode 100644
index 0000000..8d026c4
--- /dev/null
+++ b/src/main/java/io/github/linwancen/plugin/comment/utils/CommentFactory.java
@@ -0,0 +1,35 @@
+package io.github.linwancen.plugin.comment.utils;
+
+import com.intellij.psi.*;
+import com.intellij.psi.javadoc.PsiDocComment;
+import org.jetbrains.annotations.Nullable;
+
+public class CommentFactory {
+
+ private CommentFactory() {}
+
+ public static PsiDocComment fromSrcOrByteCode(PsiDocCommentOwner psiElement) {
+ PsiElement navElement = psiElement.getNavigationElement();
+ if (navElement instanceof PsiDocCommentOwner) {
+ psiElement = (PsiDocCommentOwner) navElement;
+ }
+ return psiElement.getDocComment();
+ }
+
+ @Nullable
+ public static PsiDocComment from(PsiFile psiFile) {
+ if (!(psiFile instanceof PsiJavaFile)) {
+ return null;
+ }
+ PsiJavaFile psiJavaFile = (PsiJavaFile) psiFile;
+ if (PsiPackage.PACKAGE_INFO_FILE.equals(psiFile.getName())) {
+ return PsiPackageCommentFactory.fromPackageInfoFile(psiFile);
+ }
+ PsiClass[] classes = psiJavaFile.getClasses();
+ if (classes.length == 0) {
+ return null;
+ }
+ PsiClass psiClass = classes[0];
+ return fromSrcOrByteCode(psiClass);
+ }
+}
diff --git a/src/main/java/io/github/linwancen/plugin/comment/utils/PsiDocCommentUtils.java b/src/main/java/io/github/linwancen/plugin/comment/utils/PsiDocCommentUtils.java
new file mode 100644
index 0000000..c09d172
--- /dev/null
+++ b/src/main/java/io/github/linwancen/plugin/comment/utils/PsiDocCommentUtils.java
@@ -0,0 +1,52 @@
+package io.github.linwancen.plugin.comment.utils;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.javadoc.PsiDocComment;
+import com.intellij.psi.javadoc.PsiDocToken;
+import com.intellij.psi.javadoc.PsiInlineDocTag;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PsiDocCommentUtils {
+
+ private PsiDocCommentUtils() {}
+
+ @Nullable
+ public static String getCommentText(@Nullable PsiDocComment psiDocComment) {
+ if (psiDocComment == null) {
+ return null;
+ }
+ List comments = new ArrayList<>();
+ PsiElement[] elements = psiDocComment.getDescriptionElements();
+ for (PsiElement element : elements) {
+ if (element instanceof PsiDocToken) {
+ PsiDocToken psiDocToken = (PsiDocToken) element;
+ comments.add(psiDocToken.getText());
+ } else if (element instanceof PsiInlineDocTag) {
+ PsiInlineDocTag psiInlineDocTag = (PsiInlineDocTag) element;
+ PsiElement[] children = psiInlineDocTag.getChildren();
+ if (children.length > 2) {
+ comments.add(children[2].getText());
+ }
+ }
+ if (comments.size() > 1) {
+ break;
+ }
+ }
+ if (comments.isEmpty()) {
+ return null;
+ }
+ StringBuilder sb = new StringBuilder(comments.get(0).trim());
+ if (sb.length() == 0) {
+ return null;
+ }
+ if (comments.size() > 1) {
+ sb.append(" ").append(comments.get(1).trim().replace("
", ""));
+ }
+ sb.insert(0, " ");
+ sb.append(" ");
+ return sb.toString();
+ }
+}
diff --git a/src/main/java/io/github/linwancen/plugin/comment/utils/PsiMethodCommentFactory.java b/src/main/java/io/github/linwancen/plugin/comment/utils/PsiMethodCommentFactory.java
new file mode 100644
index 0000000..267c9c9
--- /dev/null
+++ b/src/main/java/io/github/linwancen/plugin/comment/utils/PsiMethodCommentFactory.java
@@ -0,0 +1,71 @@
+package io.github.linwancen.plugin.comment.utils;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.javadoc.PsiDocComment;
+import org.jetbrains.annotations.Nullable;
+
+public class PsiMethodCommentFactory {
+
+ private PsiMethodCommentFactory() {}
+
+ @Nullable
+ public static PsiDocComment from(PsiMethod psiMethod) {
+ // .class
+ PsiElement navElement = psiMethod.getNavigationElement();
+ if (navElement instanceof PsiMethod) {
+ psiMethod = (PsiMethod) navElement;
+ }
+
+ PsiDocComment docComment = psiMethod.getDocComment();
+ if (docComment != null) {
+ return docComment;
+ }
+
+ // supper
+ PsiDocComment superDoc = supperMethodComment(psiMethod);
+ if (superDoc != null) {
+ return superDoc;
+ }
+
+ // get/set/is - PropertyDescriptor getReadMethod() getWriteMethod()
+ return propMethodComment(psiMethod, psiMethod.getContainingClass());
+ }
+
+ @Nullable
+ public static PsiDocComment supperMethodComment(PsiMethod psiMethod) {
+ PsiMethod[] superMethods = psiMethod.findSuperMethods();
+ for (PsiMethod superMethod : superMethods) {
+ PsiDocComment superDoc = from(superMethod);
+ if (superDoc != null) {
+ return superDoc;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ public static PsiDocComment propMethodComment(PsiMethod psiMethod, PsiClass psiClass) {
+ if (psiClass == null) {
+ return null;
+ }
+ String name = psiMethod.getName();
+ if (name.length() > 3 && (name.startsWith("get") || name.startsWith("set"))) {
+ name = name.substring(3);
+ } else if (name.length() > 2 && name.startsWith("is")) {
+ name = name.substring(2);
+ } else {
+ return null;
+ }
+ char[] chars = name.toCharArray();
+ chars[0] += 32;
+ name = String.valueOf(chars);
+ PsiField fieldByName = psiClass.findFieldByName(name, false);
+ if (fieldByName == null) {
+ return null;
+ }
+ return fieldByName.getDocComment();
+ }
+}
diff --git a/src/main/java/io/github/linwancen/plugin/comment/utils/PsiPackageCommentFactory.java b/src/main/java/io/github/linwancen/plugin/comment/utils/PsiPackageCommentFactory.java
new file mode 100644
index 0000000..580c8b4
--- /dev/null
+++ b/src/main/java/io/github/linwancen/plugin/comment/utils/PsiPackageCommentFactory.java
@@ -0,0 +1,59 @@
+package io.github.linwancen.plugin.comment.utils;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.impl.source.tree.JavaDocElementType;
+import com.intellij.psi.impl.source.tree.JavaElementType;
+import com.intellij.psi.javadoc.PsiDocComment;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class PsiPackageCommentFactory {
+
+ private PsiPackageCommentFactory() {}
+
+ @Nullable
+ public static PsiDocComment from(PsiPackage psiPackage) {
+ PsiDirectory[] psiDirectories = psiPackage.getDirectories();
+ for (PsiDirectory psiDirectory : psiDirectories) {
+ PsiDocComment psiDocComment = from(psiDirectory);
+ if (psiDocComment != null) {
+ return psiDocComment;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ public static PsiDocComment from(PsiDirectory psiDirectory) {
+ PsiFile packageInfoFile = psiDirectory.findFile(PsiPackage.PACKAGE_INFO_FILE);
+ return fromPackageInfoFile(packageInfoFile);
+ }
+
+ @Nullable
+ public static PsiDocComment fromPackageInfoFile(PsiFile packageInfoFile) {
+ if (packageInfoFile == null) {
+ return null;
+ }
+ ASTNode astNode = packageInfoFile.getNode();
+ if (astNode == null) {
+ return null;
+ }
+ ASTNode docCommentNode = findRelevantCommentNode(astNode);
+ if (docCommentNode == null) {
+ return null;
+ }
+ return (PsiDocComment) docCommentNode;
+ }
+
+ private static ASTNode findRelevantCommentNode(@NotNull ASTNode fileNode) {
+ ASTNode node = fileNode.findChildByType(JavaElementType.PACKAGE_STATEMENT);
+ if (node == null) node = fileNode.getLastChildNode();
+ while (node != null && node.getElementType() != JavaDocElementType.DOC_COMMENT) {
+ node = node.getTreePrev();
+ }
+ return node;
+ }
+}
diff --git a/src/main/java/io/github/linwancen/plugin/comment/utils/SkipUtils.java b/src/main/java/io/github/linwancen/plugin/comment/utils/SkipUtils.java
new file mode 100644
index 0000000..9605d56
--- /dev/null
+++ b/src/main/java/io/github/linwancen/plugin/comment/utils/SkipUtils.java
@@ -0,0 +1,16 @@
+package io.github.linwancen.plugin.comment.utils;
+
+import com.intellij.psi.PsiClass;
+
+public class SkipUtils {
+
+ private SkipUtils() {}
+
+ public static boolean skip(PsiClass psiClass) {
+ if (psiClass == null) {
+ return true;
+ }
+ String name = psiClass.getQualifiedName();
+ return name == null || name.startsWith("java");
+ }
+}
diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml
new file mode 100644
index 0000000..7946ca3
--- /dev/null
+++ b/src/main/resources/META-INF/plugin.xml
@@ -0,0 +1,37 @@
+
+ io.github.linwancen.show-comment
+ Show Comment
+ 林万程
+
+
+ Show javadoc comments for calling methods at the end of the line.
+ Show javadoc comments in the Project view Tree structure.
+
+ Chinese Note:
+
+ - 在行末显示调用方法的文档注释。
+
- 在结构树显示文档注释。
+
+ ]]>
+
+
+ com.intellij.modules.platform
+ com.intellij.modules.java
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file