Introduce method reference type; mute type check for it

This commit is contained in:
Roman Shevchenko
2012-06-04 12:19:08 +04:00
parent a55a6dd51b
commit bd86a3e9bd
10 changed files with 138 additions and 76 deletions
@@ -2610,6 +2610,10 @@ public class HighlightUtil {
@Nullable
public static HighlightInfo checkMethodReferencesFeature(final PsiMethodReferenceExpression expression) {
return checkFeature(expression, Feature.METHOD_REFERENCES);
final HighlightInfo info = checkFeature(expression, Feature.METHOD_REFERENCES);
if (info != null) return info;
// todo[r.sh] stub; remove after implementing support in TypeConversionUtil
final String message = "Method references type check is not yet implemented";
return HighlightInfo.createHighlightInfo(HighlightInfoType.WEAK_WARNING, expression, message);
}
}
@@ -0,0 +1,73 @@
/*
* 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.
*/
package com.intellij.psi;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/**
* A type which represents a function denoted by a method reference.
*/
public class PsiMethodReferenceType extends PsiType {
private final PsiMethodReferenceExpression myReference;
public PsiMethodReferenceType(@NotNull final PsiMethodReferenceExpression reference) {
super(PsiAnnotation.EMPTY_ARRAY);
myReference = reference;
}
@Override
public String getPresentableText() {
return "<method reference>";
}
@Override
public String getCanonicalText() {
return getPresentableText();
}
@Override
public String getInternalCanonicalText() {
return getPresentableText();
}
@Override
public boolean isValid() {
return myReference.isValid();
}
@Override
public boolean equalsToText(@NonNls final String text) {
return false;
}
@Override
public <A> A accept(@NotNull final PsiTypeVisitor<A> visitor) {
return visitor.visitMethodReferenceType(this);
}
@Override
public GlobalSearchScope getResolveScope() {
return null;
}
@NotNull
@Override
public PsiType[] getSuperTypes() {
return PsiType.EMPTY_ARRAY;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* 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.
@@ -56,4 +56,8 @@ public class PsiTypeVisitor<A> {
public A visitDiamondType(PsiDiamondType diamondType) {
return visitType(diamondType);
}
public A visitMethodReferenceType(PsiMethodReferenceType methodReferenceType) {
return visitType(methodReferenceType);
}
}
@@ -637,10 +637,14 @@ public class TypeConversionUtil {
public static boolean isAssignable(@NotNull PsiType left, @NotNull PsiType right, boolean allowUncheckedConversion) {
if (left == right || left.equals(right)) return true;
if (isNullType(right)) {
return !(left instanceof PsiPrimitiveType) || isNullType(left);
}
// todo[r.sh] implement
if (right instanceof PsiMethodReferenceType && left instanceof PsiClassType) return true;
if (left instanceof PsiIntersectionType) {
PsiType[] conjuncts = ((PsiIntersectionType)left).getConjuncts();
for (PsiType conjunct : conjuncts) {
@@ -44,8 +44,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
@Override
public PsiType getType() {
// todo[r.sh]: implement
return null;
return new PsiMethodReferenceType(this);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* 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.
@@ -157,6 +157,7 @@ public class ReplaceExpressionUtil {
i == JavaElementType.ARRAY_ACCESS_EXPRESSION ||
i == JavaElementType.ARRAY_INITIALIZER_EXPRESSION ||
i == JavaElementType.JAVA_CODE_REFERENCE ||
i == JavaElementType.METHOD_REF_EXPRESSION ||
i == JavaElementType.EMPTY_EXPRESSION) {
return 14;
}
@@ -19,8 +19,10 @@ class C {
void m();
}
void simplest() { }
void use(Simplest s) { }
void test() {
<error descr="Incompatible types. Found: 'null', required: 'C.Simplest'">Simplest simplest = this::simplest;</error>
Simplest simplest = <weak_warning descr="Method references type check is not yet implemented">this::simplest</weak_warning>;
use(<weak_warning descr="Method references type check is not yet implemented">this::simplest</weak_warning>);
}
}
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.daemon;
import com.intellij.ExtensionPoints;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.compiler.JavacQuirksInspection;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
@@ -43,10 +44,16 @@ import java.util.List;
public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
@NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/advHighlighting7";
private void doTest(boolean checkWarnings, boolean checkInfos) throws Exception {
private void doTest(boolean checkWarnings, boolean checkInfos, InspectionProfileEntry... tools) throws Exception {
for (InspectionProfileEntry tool : tools) { enableInspectionTool(tool); }
doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkInfos);
}
private void doTest(boolean checkWarnings, boolean checkWeakWarnings, boolean checkInfos, InspectionProfileEntry... tools) throws Exception {
for (InspectionProfileEntry tool : tools) { enableInspectionTool(tool); }
doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkWeakWarnings, checkInfos);
}
@Override
protected LocalInspectionTool[] configureLocalInspectionTools() {
return new LocalInspectionTool[]{
@@ -92,46 +99,14 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
public void testDynamicallyAddIgnoredAnnotations() throws Exception {
ExtensionPoint<EntryPoint> point = Extensions.getRootArea().getExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL);
EntryPoint extension = new EntryPoint() {
@NotNull
@Override
public String getDisplayName() {
return "duh";
}
@Override
public boolean isEntryPoint(RefElement refElement, PsiElement psiElement) {
return false;
}
@Override
public boolean isEntryPoint(PsiElement psiElement) {
return false;
}
@Override
public boolean isSelected() {
return false;
}
@Override
public void setSelected(boolean selected) {
}
@Override
public void readExternal(Element element) {
}
@Override
public void writeExternal(Element element) {
}
@Override
public String[] getIgnoreAnnotations() {
return new String[]{"MyAnno"};
}
@NotNull @Override public String getDisplayName() { return "duh"; }
@Override public boolean isEntryPoint(RefElement refElement, PsiElement psiElement) { return false; }
@Override public boolean isEntryPoint(PsiElement psiElement) { return false; }
@Override public boolean isSelected() { return false; }
@Override public void setSelected(boolean selected) { }
@Override public void readExternal(Element element) { }
@Override public void writeExternal(Element element) { }
@Override public String[] getIgnoreAnnotations() { return new String[]{"MyAnno"}; }
};
UnusedDeclarationInspection deadCodeInspection = new UnusedDeclarationInspection();
@@ -156,33 +131,19 @@ 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 testTryWithResourcesWarn() throws Exception {
enableInspectionTool(new DefUseInspection());
doTest(true, false);
}
public void testTryWithResourcesWarn() throws Exception { doTest(true, false, new DefUseInspection()); }
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());
doTest(true, false);
}
public void testUnused() throws Exception {
enableInspectionTool(new UnusedDeclarationInspection());
doTest(true, false);
}
public void testErasureClashConfusion() throws Exception { doTest(true, false, new UnusedDeclarationInspection()); }
public void testUnused() throws Exception { doTest(true, false, new UnusedDeclarationInspection()); }
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 testExtensionMethods() throws Exception { doTest(false, false); }
public void testMethodReferences() throws Exception { doTest(false, false); }
public void testMethodReferences() throws Exception { doTest(false, true, false); }
}
@@ -79,10 +79,19 @@ public abstract class LightDaemonAnalyzerTestCase extends LightCodeInsightTestCa
doTestConfiguredFile(checkWarnings, checkInfos, filePath);
}
protected void doTest(@NonNls String filePath, boolean checkWarnings, boolean checkWeakWarnings, boolean checkInfos) throws Exception {
configureByFile(filePath);
doTestConfiguredFile(checkWarnings, checkWeakWarnings, checkInfos, filePath);
}
protected void doTestConfiguredFile(boolean checkWarnings, boolean checkInfos, @Nullable String filePath) {
doTestConfiguredFile(checkWarnings, false, checkInfos, filePath);
}
protected void doTestConfiguredFile(boolean checkWarnings, boolean checkWeakWarnings, boolean checkInfos, @Nullable String filePath) {
getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
ExpectedHighlightingData data = new ExpectedHighlightingData(getEditor().getDocument(), checkWarnings, checkInfos);
ExpectedHighlightingData data = new ExpectedHighlightingData(getEditor().getDocument(), checkWarnings, checkWeakWarnings, checkInfos);
checkHighlighting(data, composeLocalPath(filePath));
}
@@ -22,12 +22,10 @@ import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.hint.HintManagerImpl;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInspection.GlobalInspectionTool;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.codeInspection.ex.InspectionTool;
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
import com.intellij.codeInspection.ex.ToolsImpl;
import com.intellij.codeInspection.ex.*;
import com.intellij.ide.highlighter.ProjectFileType;
import com.intellij.ide.startup.StartupManagerEx;
import com.intellij.ide.startup.impl.StartupManagerImpl;
@@ -423,12 +421,19 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
}
}
protected void enableInspectionTool(LocalInspectionTool tool){
enableInspectionTool(new LocalInspectionToolWrapper(tool));
}
protected void enableInspectionTool(InspectionTool tool){
enableInspectionTool(myAvailableInspectionTools, tool);
protected void enableInspectionTool(@NotNull InspectionProfileEntry tool) {
if (tool instanceof InspectionTool) {
enableInspectionTool(myAvailableInspectionTools, (InspectionTool)tool);
}
else if (tool instanceof LocalInspectionTool) {
enableInspectionTool(myAvailableInspectionTools, new LocalInspectionToolWrapper((LocalInspectionTool)tool));
}
else if (tool instanceof GlobalInspectionTool) {
enableInspectionTool(myAvailableInspectionTools, new GlobalInspectionToolWrapper((GlobalInspectionTool)tool));
}
else {
throw new IllegalArgumentException("Unexpected inspection type: " + tool);
}
}
private static void enableInspectionTool(final Map<String, InspectionTool> availableLocalTools, InspectionTool wrapper) {