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