diff --git a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index 51e0f897419c..1e101063e50c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -365,7 +365,7 @@ public class JavaDocInfoGenerator { return packageName; } - public boolean generateDocInfoCore (StringBuilder buffer, boolean generatePrologueAndEpilogue) { + public boolean generateDocInfoCore(StringBuilder buffer, boolean generatePrologueAndEpilogue) { if (myElement instanceof PsiClass) { generateClassJavaDoc(buffer, (PsiClass)myElement, generatePrologueAndEpilogue); } @@ -387,7 +387,10 @@ public class JavaDocInfoGenerator { generatePackageJavaDoc(buffer, aPackage, generatePrologueAndEpilogue); } else if (myElement instanceof PsiPackage) { - generatePackageJavaDoc(buffer, (PsiPackage) myElement, generatePrologueAndEpilogue); + generatePackageJavaDoc(buffer, (PsiPackage)myElement, generatePrologueAndEpilogue); + } + else if (myElement instanceof PsiJavaModule) { + generateModuleJavaDoc(buffer, (PsiJavaModule)myElement, generatePrologueAndEpilogue); } else { return false; @@ -723,6 +726,19 @@ public class JavaDocInfoGenerator { } } + private void generateModuleJavaDoc(StringBuilder buffer, PsiJavaModule module, boolean generatePrologueAndEpilogue) { + if (generatePrologueAndEpilogue) generatePrologue(buffer); + + buffer.append("
module ").append(module.getName()).append("");
+
+ PsiDocComment comment = module.getDocComment();
+ if (comment != null) {
+ generateCommonSection(buffer, comment);
+ }
+
+ if (generatePrologueAndEpilogue) generateEpilogue(buffer);
+ }
+
/**
* Finds doc comment immediately preceding package statement
*/
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java b/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java
index 341cf41343cf..11f3f622b205 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java
@@ -22,7 +22,7 @@ import org.jetbrains.annotations.NotNull;
*
* @since 2016.3
*/
-public interface PsiJavaModule extends NavigatablePsiElement, PsiNamedElement {
+public interface PsiJavaModule extends NavigatablePsiElement, PsiNamedElement, PsiJavaDocumentedElement {
String MODULE_INFO_CLASS = "module-info";
String MODULE_INFO_FILE = MODULE_INFO_CLASS + ".java";
String MODULE_INFO_CLS_FILE = MODULE_INFO_CLASS + ".class";
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java
index 572707325034..db152ddea456 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -110,7 +110,9 @@ public class JavaParserUtil {
}
}
- private static final TokenSet PRECEDING_COMMENT_SET = ElementType.FULL_MEMBER_BIT_SET;
+ private static final TokenSet PRECEDING_COMMENT_SET = TokenSet.orSet(
+ TokenSet.create(JavaElementType.MODULE), ElementType.FULL_MEMBER_BIT_SET);
+
private static final TokenSet TRAILING_COMMENT_SET = TokenSet.orSet(
TokenSet.create(JavaElementType.PACKAGE_STATEMENT),
ElementType.IMPORT_STATEMENT_BASE_BIT_SET, ElementType.FULL_MEMBER_BIT_SET, ElementType.JAVA_STATEMENT_BIT_SET);
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/ModuleParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/ModuleParser.java
index 9216f033cb5a..4eac9ca4cb33 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/parser/ModuleParser.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/ModuleParser.java
@@ -61,7 +61,7 @@ public class ModuleParser {
parseModuleContent(builder);
}
- module.done(JavaElementType.MODULE);
+ JavaParserUtil.done(module, JavaElementType.MODULE);
if (builder.getTokenType() != null) {
parseExtras(builder, JavaErrorMessages.message("unexpected.tokens"));
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaModuleImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaModuleImpl.java
index 7f23ea99588b..42fbc9ff4b4e 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaModuleImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaModuleImpl.java
@@ -22,9 +22,11 @@ import com.intellij.psi.impl.java.stubs.PsiJavaModuleStub;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.TreeElement;
+import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
public class ClsJavaModuleImpl extends ClsRepositoryPsiElement+ module + M.N ++ """.trimIndent()) + + fun testDocumentedModule() = doTestModule("/** One humble module. */\nmodule M.N { }", """ + +
+ module + M.N ++ One humble module. + """.trimIndent()) + + private fun doTestModule(text: String, expected: String) { + val file = myFixture.configureByText("module-info.java", text) + val module = (file as PsiJavaFile).moduleDeclaration!! + val docInfo = JavaDocInfoGeneratorFactory.create(project, module).generateDocInfo(null)!! + val body = JDOMUtil.loadDocument(docInfo).rootElement.getChild("body") + assertThat(body).isEqualTo(expected) + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/dangling_javadoc/module-info.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/dangling_javadoc/module-info.java new file mode 100644 index 000000000000..6013b8548fdd --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/javadoc/dangling_javadoc/module-info.java @@ -0,0 +1,4 @@ +/** + * A nice little module. + */ +module M { } \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/javadoc/DanglingJavadocInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/javadoc/DanglingJavadocInspectionTest.java index 085e134de0fb..77e83552560f 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/javadoc/DanglingJavadocInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/javadoc/DanglingJavadocInspectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,13 @@ package com.siyeh.ig.javadoc; import com.intellij.codeInspection.InspectionProfileEntry; +import com.intellij.openapi.roots.LanguageLevelModuleExtension; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.siyeh.ig.LightInspectionTestCase; import org.jetbrains.annotations.Nullable; +import static com.intellij.pom.java.LanguageLevel.JDK_1_9; + /** * @author Bas Leijdekkers */ @@ -32,9 +36,14 @@ public class DanglingJavadocInspectionTest extends LightInspectionTestCase { doNamedTest("package-info"); } + public void testModuleInfo() { + ModuleRootModificationUtil.updateModel(myModule, m -> m.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(JDK_1_9)); + doNamedTest("module-info"); + } + @Nullable @Override protected InspectionProfileEntry getInspection() { return new DanglingJavadocInspection(); } -} +} \ No newline at end of file