Do not highlight extension methods' bodies

This commit is contained in:
Roman Shevchenko
2012-05-24 21:43:35 +04:00
parent df60337ea6
commit 5a7dd97108
7 changed files with 104 additions and 181 deletions
@@ -838,14 +838,19 @@ public class HighlightMethodUtil {
return null;
}
@Nullable
static HighlightInfo checkMethodCanHaveBody(PsiMethod method) {
if (method.getBody() == null) return null;
PsiClass aClass = method.getContainingClass();
String message = null;
if (aClass != null && aClass.isInterface()) {
message = JavaErrorMessages.message("interface.methods.cannot.have.body");
if (!PsiUtil.isExtensionMethod(method)) {
message = JavaErrorMessages.message("interface.methods.cannot.have.body");
}
else {
return HighlightUtil.checkExtensionMethodsFeature(method);
}
}
else if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
message = JavaErrorMessages.message("abstract.methods.cannot.have.a.body");
@@ -853,21 +858,19 @@ public class HighlightMethodUtil {
else if (method.hasModifierProperty(PsiModifier.NATIVE)) {
message = JavaErrorMessages.message("native.methods.cannot.have.a.body");
}
if (message == null) return null;
if (message != null) {
TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method);
HighlightInfo info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, textRange, message);
QuickFixAction.registerQuickFixAction(info, new DeleteMethodBodyFix(method));
if (method.hasModifierProperty(PsiModifier.ABSTRACT) && aClass != null && !aClass.isInterface()) {
IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(method, PsiModifier.ABSTRACT, false, false);
QuickFixAction.registerQuickFixAction(info, fix);
}
return info;
TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method);
HighlightInfo info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, textRange, message);
QuickFixAction.registerQuickFixAction(info, new DeleteMethodBodyFix(method));
if (method.hasModifierProperty(PsiModifier.ABSTRACT) && aClass != null && !aClass.isInterface()) {
IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(method, PsiModifier.ABSTRACT, false, false);
QuickFixAction.registerQuickFixAction(info, fix);
}
return null;
return info;
}
@Nullable
static HighlightInfo checkConstructorCallMustBeFirstStatement(PsiReferenceExpression expression) {
PsiElement methodCall = expression.getParent();
if (!HighlightUtil.isSuperOrThisMethodCall(methodCall)) return null;
@@ -2481,7 +2481,8 @@ public class HighlightUtil {
VARARGS(LanguageLevel.JDK_1_5, "feature.varargs"),
DIAMOND_TYPES(LanguageLevel.JDK_1_7, "feature.diamond.types"),
MULTI_CATCH(LanguageLevel.JDK_1_7, "feature.multi.catch"),
TRY_WITH_RESOURCES(LanguageLevel.JDK_1_7, "feature.try.with.resources");
TRY_WITH_RESOURCES(LanguageLevel.JDK_1_7, "feature.try.with.resources"),
EXTENSION_METHODS(LanguageLevel.JDK_1_8, "feature.extension.methods");
private final LanguageLevel level;
private final String key;
@@ -2544,4 +2545,9 @@ public class HighlightUtil {
public static HighlightInfo checkTryWithResourcesFeature(final PsiResourceVariable resourceVariable) {
return checkFeature(resourceVariable.getParent(), Feature.TRY_WITH_RESOURCES);
}
@Nullable
public static HighlightInfo checkExtensionMethodsFeature(final PsiMethod method) {
return checkFeature(method, Feature.EXTENSION_METHODS);
}
}
@@ -318,7 +318,9 @@ public final class PsiUtil extends PsiUtilCore {
@PsiModifier.ModifierConstant
@Nullable
public static String getAccessModifier(int accessLevel) {
return accessLevel > accessModifiers.length ? null : accessModifiers[accessLevel - 1];
@SuppressWarnings("UnnecessaryLocalVariable") @PsiModifier.ModifierConstant
final String modifier = accessLevel > accessModifiers.length ? null : accessModifiers[accessLevel - 1];
return modifier;
}
private static final String[] accessModifiers = {
@@ -952,4 +954,12 @@ public final class PsiUtil extends PsiUtilCore {
public static boolean isIgnoredName(@Nullable final String name) {
return "ignore".equals(name) || "ignored".equals(name);
}
public static boolean isExtensionMethod(@Nullable final PsiMethod method) {
if (method == null) return false;
final PsiCodeBlock body = method.getBody();
if (body == null) return false;
final PsiElement previous = PsiTreeUtil.skipSiblingsBackward(body, PsiComment.class, PsiWhiteSpace.class);
return isJavaToken(previous, JavaTokenType.DEFAULT_KEYWORD);
}
}
@@ -349,6 +349,7 @@ feature.static.imports=Static imports
feature.for.each=For-each loops
feature.varargs=Variable arity methods
feature.diamond.types=Diamond types
feature.try.with.resources=Try-with-resources
feature.multi.catch=Multi-catches
feature.try.with.resources=Try-with-resources
feature.extension.methods=Extension methods
insufficient.language.level={0} are not supported at this language level
@@ -38,4 +38,8 @@ class UnsupportedFeatures {
try <error descr="Try-with-resources are not supported at this language level">(Reader r = new FileReader("/dev/null"))</error> { }
}
interface I {
<error descr="Extension methods are not supported at this language level">void m() default { }</error>
}
}
@@ -0,0 +1,21 @@
/*
* Copyright 2000-2012 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.
*/
class C {
interface I {
<error descr="Interface methods cannot have body">void m1()</error> { }
void m2() default { }
}
}
@@ -57,126 +57,36 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
};
}
public void testAllJava15Features() throws Exception {
doTest(false, false);
}
public void testEnumSyntheticMethods() throws Exception {
doTest(false, false);
}
public void testDuplicateAnnotations() throws Exception {
doTest(false, false);
}
public void testSwitchByString() throws Exception {
doTest(false, false);
}
public void testSwitchByInaccessibleEnum() throws Exception {
doTest(false, false);
}
public void testDiamondPos1() throws Exception {
doTest(false, false);
}
public void testDiamondPos2() throws Exception {
doTest(false, false);
}
public void testDiamondPos3() throws Exception {
doTest(false, false);
}
public void testDiamondPos4() throws Exception {
doTest(false, false);
}
public void testDiamondPos5() throws Exception {
doTest(false, false);
}
public void testDiamondPos6() throws Exception {
doTest(false, false);
}
public void testDiamondPos7() throws Exception {
doTest(false, false);
}
public void testDiamondNeg15() throws Exception {
doTest(false, false);
}
public void testDiamondPos9() throws Exception {
doTest(false, false);
}
public void testDiamondNeg1() throws Exception {
doTest(false, false);
}
public void testDiamondNeg2() throws Exception {
doTest(false, false);
}
public void testDiamondNeg3() throws Exception {
doTest(false, false);
}
public void testDiamondNeg4() throws Exception {
doTest(false, false);
}
public void testDiamondNeg5() throws Exception {
doTest(false, false);
}
public void testDiamondNeg6() throws Exception {
doTest(false, false);
}
public void testDiamondNeg7() throws Exception {
doTest(false, false);
}
public void testDiamondNeg8() throws Exception {
doTest(false, false);
}
public void testDiamondNeg9() throws Exception {
doTest(false, false);
}
public void testDiamondNeg10() throws Exception {
doTest(false, false);
}
public void testDiamondNeg11() throws Exception {
doTest(false, false);
}
public void testDiamondNeg12() throws Exception {
doTest(false, false);
}
public void testDiamondNeg13() throws Exception {
doTest(false, false);
}
public void testDiamondNeg14() throws Exception {
doTest(false, false);
}
public void testDiamondMisc() throws Exception {
doTest(false, false);
}
public void testHighlightInaccessibleFromClassModifierList() throws Exception {
doTest(false, false);
}
public void testAllJava15Features() throws Exception { doTest(false, false); }
public void testEnumSyntheticMethods() throws Exception { doTest(false, false); }
public void testDuplicateAnnotations() throws Exception { doTest(false, false); }
public void testSwitchByString() throws Exception { doTest(false, false); }
public void testSwitchByInaccessibleEnum() throws Exception { doTest(false, false); }
public void testDiamondPos1() throws Exception { doTest(false, false); }
public void testDiamondPos2() throws Exception { doTest(false, false); }
public void testDiamondPos3() throws Exception { doTest(false, false); }
public void testDiamondPos4() throws Exception { doTest(false, false); }
public void testDiamondPos5() throws Exception { doTest(false, false); }
public void testDiamondPos6() throws Exception { doTest(false, false); }
public void testDiamondPos7() throws Exception { doTest(false, false); }
public void testDiamondNeg15() throws Exception { doTest(false, false); }
public void testDiamondPos9() throws Exception { doTest(false, false); }
public void testDiamondNeg1() throws Exception { doTest(false, false); }
public void testDiamondNeg2() throws Exception { doTest(false, false); }
public void testDiamondNeg3() throws Exception { doTest(false, false); }
public void testDiamondNeg4() throws Exception { doTest(false, false); }
public void testDiamondNeg5() throws Exception { doTest(false, false); }
public void testDiamondNeg6() throws Exception { doTest(false, false); }
public void testDiamondNeg7() throws Exception { doTest(false, false); }
public void testDiamondNeg8() throws Exception { doTest(false, false); }
public void testDiamondNeg9() throws Exception { doTest(false, false); }
public void testDiamondNeg10() throws Exception { doTest(false, false); }
public void testDiamondNeg11() throws Exception { doTest(false, false); }
public void testDiamondNeg12() throws Exception { doTest(false, false); }
public void testDiamondNeg13() throws Exception { doTest(false, false); }
public void testDiamondNeg14() throws Exception { doTest(false, false); }
public void testDiamondMisc() throws Exception { doTest(false, false); }
public void testHighlightInaccessibleFromClassModifierList() throws Exception { doTest(false, false); }
public void testDynamicallyAddIgnoredAnnotations() throws Exception {
ExtensionPoint<EntryPoint> point = Extensions.getRootArea().getExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL);
@@ -242,46 +152,21 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
}
}
public void testNumericLiterals() throws Exception {
doTest(false, false);
}
public void testMultiCatch() throws Exception {
doTest(false, false);
}
public void testTryWithResources() throws Exception {
doTest(false, false);
}
public void testNumericLiterals() throws Exception { doTest(false, false); }
public void testMultiCatch() throws Exception { doTest(false, false); }
public void testTryWithResources() throws Exception { doTest(false, false); }
public void testTryWithResourcesWarn() throws Exception {
enableInspectionTool(new DefUseInspection());
doTest(true, false);
}
public void testSafeVarargsApplicability() throws Exception {
doTest(true, false);
}
public void testUncheckedGenericsArrayCreation() throws Exception {
doTest(true, false);
}
public void testPreciseRethrow() throws Exception {
doTest(false, false);
}
public void testImprovedCatchAnalysis() throws Exception {
doTest(true, false);
}
public void testJavacQuirks() throws Exception {
doTest(true, false);
}
public void testPolymorphicTypeCast() throws Exception {
doTest(true, false);
}
public void testSafeVarargsApplicability() throws Exception { doTest(true, false); }
public void testUncheckedGenericsArrayCreation() throws Exception { doTest(true, false); }
public void testPreciseRethrow() throws Exception { doTest(false, false); }
public void testImprovedCatchAnalysis() throws Exception { doTest(true, false); }
public void testJavacQuirks() throws Exception { doTest(true, false); }
public void testPolymorphicTypeCast() throws Exception { doTest(true, false); }
public void testErasureClashConfusion() throws Exception {
enableInspectionTool(new UnusedDeclarationInspection());
@@ -293,16 +178,9 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
doTest(true, false);
}
public void testSuperBound() throws Exception {
doTest(false, false);
}
public void testExtendsBound() throws Exception {
doTest(false, false);
}
public void testSuperBound() throws Exception { doTest(false, false); }
public void testExtendsBound() throws Exception { doTest(false, false); }
public void testIDEA84533() throws Exception { doTest(false, false); }
public void testClassLiteral() throws Exception { doTest(false, false);}
public void testClassLiteral() throws Exception { doTest(false, false); }
public void testExtensionMethods() throws Exception { doTest(false, false); }
}