[java] highlights illegal modifiers in 'requires java.base' (IDEA-184708)

This commit is contained in:
Roman Shevchenko
2018-02-07 19:04:03 +01:00
parent 59cd135a37
commit 3a3a63bcc1
6 changed files with 63 additions and 2 deletions
@@ -1745,6 +1745,9 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
PsiJavaModule container = (PsiJavaModule)statement.getParent();
PsiJavaModuleReferenceElement ref = statement.getReferenceElement();
if (!myHolder.hasErrorResults()) myHolder.add(ModuleHighlightUtil.checkModuleReference(ref, container));
if (!myHolder.hasErrorResults() && myLanguageLevel.isAtLeast(LanguageLevel.JDK_10)) {
myHolder.addAll(ModuleHighlightUtil.checkModifiers(statement));
}
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
@@ -47,6 +47,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.intellij.openapi.module.ModuleUtilCore.findModuleForFile;
import static com.intellij.psi.SyntaxTraverser.psiTraverser;
public class ModuleHighlightUtil {
private static final Attributes.Name MULTI_RELEASE = new Attributes.Name("Multi-Release");
@@ -444,6 +445,24 @@ public class ModuleHighlightUtil {
return null;
}
@Nullable
static List<HighlightInfo> checkModifiers(@NotNull PsiRequiresStatement statement) {
PsiModifierList modList = statement.getModifierList();
if (modList != null && PsiJavaModule.JAVA_BASE.equals(statement.getModuleName())) {
return psiTraverser().children(modList)
.filter(PsiKeyword.class)
.map(keyword -> {
@PsiModifier.ModifierConstant String modifier = keyword.getText();
String message = JavaErrorMessages.message("modifier.not.allowed", modifier);
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(keyword).descriptionAndTooltip(message).create();
QuickFixAction.registerQuickFixAction(info, factory().createModifierListFix(modList, modifier, false, false));
return info;
}).toList();
}
return null;
}
private static HighlightInfo moduleResolveError(PsiJavaModuleReferenceElement refElement, PsiPolyVariantReference ref) {
if (ref.multiResolve(true).length == 0) {
String message = JavaErrorMessages.message("module.not.found", refElement.getReferenceText());
@@ -177,6 +177,25 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor {
}
}
@Override
public void visitKeyword(PsiKeyword keyword) {
super.visitKeyword(keyword);
if (myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_9) && !myLanguageLevel.isAtLeast(LanguageLevel.JDK_10)) {
@PsiModifier.ModifierConstant String modifier = keyword.getText();
if (PsiKeyword.STATIC.equals(modifier) || PsiKeyword.TRANSITIVE.equals(modifier)) {
PsiElement parent = keyword.getParent();
if (parent instanceof PsiModifierList) {
PsiElement grand = parent.getParent();
if (grand instanceof PsiRequiresStatement && PsiJavaModule.JAVA_BASE.equals(((PsiRequiresStatement)grand).getModuleName())) {
String message = JavaErrorMessages.message("module.unwanted.modifier");
LocalQuickFix fix = QuickFixFactory.getInstance().createModifierListFix((PsiModifierList)parent, modifier, false, false);
myHolder.registerProblem(keyword, message, fix);
}
}
}
}
}
@Override
public void visitBinaryExpression(PsiBinaryExpression expression) {
super.visitBinaryExpression(expression);
@@ -84,9 +84,11 @@ public class ModifierFix extends LocalQuickFixAndIntentionActionOnPsiElement {
: containingClass != null ? containingClass.getName() : "unknown";
name = QuickFixBundle.message("class.initializer.presentation", className);
}
else if (parent instanceof PsiRequiresStatement) {
name = "requires " + ((PsiRequiresStatement)parent).getModuleName();
}
String modifierText = VisibilityUtil.toPresentableText(myModifier);
return QuickFixBundle.message(myShouldHave ? "add.modifier.fix" : "remove.modifier.fix", name, modifierText);
}
@@ -440,6 +440,8 @@ module.access.does.not.read=Package ''{0}'' is declared in module ''{1}'', but m
module.access.not.in.graph=Package ''{0}'' is declared in module ''{1}'', which is not in the module graph
module.access.bad.name=Package ''{0}'' is declared in module with an invalid name (''{1}'')
module.unwanted.modifier=Since Java 10, modifiers on 'requires java.base' are prohibited
feature.generics=Generics
feature.annotations=Annotations
feature.static.imports=Static imports
@@ -0,0 +1,16 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.java.codeInsight.daemon
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
class LightJava10HighlightingTest : LightCodeInsightFixtureTestCase() {
override fun getProjectDescriptor() = JAVA_10
fun testRequiresJavaBase() {
myFixture.configureByText("module-info.java", """
module M {
requires <error descr="Modifier 'static' not allowed here">static</error> <error descr="Modifier 'transitive' not allowed here">transitive</error> java.base;
}""".trimIndent())
myFixture.checkHighlighting()
}
}