[java] extends "module exports to itself" inspection on 'opens' statements

This commit is contained in:
Roman Shevchenko
2017-02-17 14:14:48 +01:00
parent b66aab523b
commit 7e97671afe
5 changed files with 50 additions and 99 deletions
@@ -19,14 +19,11 @@ import com.intellij.codeInsight.daemon.impl.quickfix.DeleteElementFix;
import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author Pavel.Dolgov
*/
@@ -34,31 +31,25 @@ public class Java9ModuleExportsPackageToItselfInspection extends BaseJavaLocalIn
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
PsiFile file = holder.getFile();
if (file instanceof PsiJavaFile) {
PsiJavaFile javaFile = (PsiJavaFile)file;
if (javaFile.getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_9) && javaFile.getModuleDeclaration() != null) {
return new ExportedToSelfVisitor(holder);
}
}
return PsiElementVisitor.EMPTY_VISITOR;
return PsiUtil.isModuleFile(holder.getFile()) ? new ExportedToSelfVisitor(holder) : PsiElementVisitor.EMPTY_VISITOR;
}
private static class ExportedToSelfVisitor extends JavaElementVisitor {
private final ProblemsHolder myHolder;
public ExportedToSelfVisitor(ProblemsHolder holder) { myHolder = holder; }
public ExportedToSelfVisitor(ProblemsHolder holder) {
myHolder = holder;
}
@Override
public void visitExportsStatement(PsiPackageAccessibilityStatement statement) {
super.visitExportsStatement(statement);
public void visitPackageAccessibilityStatement(PsiPackageAccessibilityStatement statement) {
super.visitPackageAccessibilityStatement(statement);
PsiJavaModule javaModule = PsiTreeUtil.getParentOfType(statement, PsiJavaModule.class);
if (javaModule != null) {
String moduleName = javaModule.getName();
List<PsiJavaModuleReferenceElement> referenceElements = ContainerUtil.newArrayList(statement.getModuleReferences());
for (PsiJavaModuleReferenceElement referenceElement : referenceElements) {
for (PsiJavaModuleReferenceElement referenceElement : statement.getModuleReferences()) {
if (moduleName.equals(referenceElement.getReferenceText())) {
String message = InspectionsBundle.message("inspection.module.exports.package.to.itself.message");
String message = InspectionsBundle.message("inspection.module.exports.package.to.itself");
String fixText = InspectionsBundle.message("exports.to.itself.delete.module.fix.name", moduleName);
myHolder.registerProblem(referenceElement, message, new DeleteElementFix(referenceElement, fixText));
}
@@ -1,70 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.daemon.quickFix
import com.intellij.codeInspection.InspectionsBundle
import com.intellij.codeInspection.java19modules.Java9ModuleExportsPackageToItselfInspection
import com.intellij.testFramework.fixtures.LightJava9ModulesCodeInsightFixtureTestCase
import com.intellij.testFramework.fixtures.MultiModuleJava9ProjectDescriptor
import org.intellij.lang.annotations.Language
import org.jetbrains.annotations.NonNls
/**
* @author Pavel.Dolgov
*/
class Java9DeleteExportsToModuleFixTest : LightJava9ModulesCodeInsightFixtureTestCase() {
val message = InspectionsBundle.message("exports.to.itself.delete.module.fix.name", "M")!!
override fun setUp() {
super.setUp()
myFixture.enableInspections(Java9ModuleExportsPackageToItselfInspection())
addFile("module-info.java", "module M2 { }", MultiModuleJava9ProjectDescriptor.ModuleDescriptor.M2)
addFile("module-info.java", "module M4 { }", MultiModuleJava9ProjectDescriptor.ModuleDescriptor.M4)
addFile("pkg/main/C.java", "package pkg.main; public class C {}")
}
fun testOnlySelfModule() {
doFix("module M { exports pkg.main to <caret>M; }",
"module M { exports pkg.main; }")
}
fun testOnlySelfModuleWithComments() {
doFix("module M { exports pkg.main to /*a*/ <caret>M /*b*/; }",
"module M { exports pkg.main /*a*/ /*b*/; }")
}
fun testSelfModuleInList() {
doFix("module M { exports pkg.main to M2, <caret>M , M4; }",
"module M { exports pkg.main to M2, M4; }")
}
fun testSelfModuleInListWithComments() {
doFix("module M { exports pkg.main to M2, /*a*/ <caret>M /*b*/,/*c*/ M4; }",
"module M { exports pkg.main to M2, /*a*/ /*b*//*c*/ M4; }")
}
private fun doFix(textBefore: String, @Language("JAVA") @NonNls textAfter: String) {
myFixture.configureByText("module-info.java", textBefore)
val action = myFixture.findSingleIntention(message)
assertNotNull(action)
myFixture.launchAction(action)
myFixture.checkHighlighting() // no warning
myFixture.checkResult("module-info.java", textAfter, false)
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -18,11 +18,15 @@ package com.intellij.codeInspection
import com.intellij.codeInspection.java19modules.Java9ModuleExportsPackageToItselfInspection
import com.intellij.testFramework.fixtures.LightJava9ModulesCodeInsightFixtureTestCase
import com.intellij.testFramework.fixtures.MultiModuleJava9ProjectDescriptor
import org.intellij.lang.annotations.Language
/**
* @author Pavel.Dolgov
*/
class Java9ModuleExportsPackageToItselfTest : LightJava9ModulesCodeInsightFixtureTestCase() {
private val message = InspectionsBundle.message("inspection.module.exports.package.to.itself")!!
private val fix = InspectionsBundle.message("exports.to.itself.delete.module.fix.name", "M")!!
override fun setUp() {
super.setUp()
myFixture.enableInspections(Java9ModuleExportsPackageToItselfInspection())
@@ -33,23 +37,50 @@ class Java9ModuleExportsPackageToItselfTest : LightJava9ModulesCodeInsightFixtur
}
fun testNoSelfModule() {
highlight("module M { exports pkg.main to M2, M4; }")
highlight("module M {\n exports pkg.main to M2, M4;\n opens pkg.main to M2, M4;\n}")
}
fun testOnlySelfModule() {
val message = InspectionsBundle.message("inspection.module.exports.package.to.itself.message")
fun testOnlySelfExport() {
highlight("module M { exports pkg.main to <warning descr=\"$message\">M</warning>; }")
fix("module M { exports pkg.main to <caret>M; }",
"module M { exports pkg.main; }")
}
fun testOnlySelfOpen() {
highlight("module M { opens pkg.main to <warning descr=\"$message\">M</warning>; }")
fix("module M { opens pkg.main to <caret>M; }",
"module M { opens pkg.main; }")
}
fun testOnlySelfModuleWithComments() {
fix("module M { exports pkg.main to /*a*/ <caret>M /*b*/; }",
"module M { exports pkg.main /*a*/ /*b*/; }")
}
fun testSelfModuleInList() {
val message = InspectionsBundle.message("inspection.module.exports.package.to.itself.message")
highlight("module M { exports pkg.main to M2, <warning descr=\"$message\">M</warning>, M4; }")
fix("module M { exports pkg.main to M2, <caret>M , M4; }",
"module M { exports pkg.main to M2, M4; }")
}
private fun highlight(text: String) = highlight("module-info.java", text)
fun testSelfModuleInListWithComments() {
fix("module M { exports pkg.main to M2, /*a*/ <caret>M /*b*/,/*c*/ M4; }",
"module M { exports pkg.main to M2, /*a*/ /*b*//*c*/ M4; }")
}
private fun highlight(path: String, text: String) {
myFixture.configureFromExistingVirtualFile(addFile(path, text))
private fun highlight(text: String) {
myFixture.configureByText("module-info.java", text)
myFixture.checkHighlighting()
}
private fun fix(textBefore: String, @Language("JAVA") textAfter: String) {
myFixture.configureByText("module-info.java", textBefore)
val action = myFixture.findSingleIntention(fix)
assertNotNull(action)
myFixture.launchAction(action)
myFixture.checkHighlighting() // no warning
myFixture.checkResult("module-info.java", textAfter, false)
}
}
@@ -751,8 +751,7 @@ inspection.lambda.to.method.call.message=Can be replaced with ''{0}''
inspection.lambda.to.method.call.fix.family.name=Replace lambda expression with method call
inspection.lambda.to.method.call.fix.name=Replace lambda expression with ''{0}''
inspection.module.exports.package.to.itself.name=Module exports package to itself
inspection.module.exports.package.to.itself.message=Module tries to export package to itself
inspection.module.exports.package.to.itself=Module exports/opens package to itself
exports.to.itself.delete.module.fix.name=Delete reference to module ''{0}''
inspection.replace.with.bulk.message=Iteration can be replaced with bulk ''{0}'' call
+1 -1
View File
@@ -905,7 +905,7 @@
<localInspection groupPath="Java" language="JAVA" shortName="Java9ModuleExportsPackageToItself"
groupBundle="messages.InspectionsBundle" groupKey="group.names.visibility.issues"
enabledByDefault="true" level="WARNING"
key="inspection.module.exports.package.to.itself.name" bundle="messages.InspectionsBundle"
key="inspection.module.exports.package.to.itself" bundle="messages.InspectionsBundle"
implementationClass="com.intellij.codeInspection.java19modules.Java9ModuleExportsPackageToItselfInspection"/>
<intentionAction>