method refs: accept 2 phase acceptance (static and receiver based), raise 'staticAccess' errors at highlighting level

This commit is contained in:
Anna Kozlova
2013-08-30 12:53:02 +04:00
parent 8cb40bfdac
commit 75847497e5
16 changed files with 185 additions and 104 deletions

View File

@@ -789,7 +789,7 @@ public class HighlightClassUtil {
if (!PsiUtil.isInnerClass(base)) return;
if (resolve == resolved && baseClass != null && (!PsiTreeUtil.isAncestor(baseClass, extendRef, true) || aClass.hasModifierProperty(PsiModifier.STATIC)) &&
!hasEnclosingInstanceInScope(baseClass, extendRef, !aClass.hasModifierProperty(PsiModifier.STATIC), true) && !qualifiedNewCalledInConstructors(aClass, baseClass)) {
!InheritanceUtil.hasEnclosingInstanceInScope(baseClass, extendRef, !aClass.hasModifierProperty(PsiModifier.STATIC), true) && !qualifiedNewCalledInConstructors(aClass, baseClass)) {
String description = JavaErrorMessages.message("no.enclosing.instance.in.scope", HighlightUtil.formatClass(baseClass));
infos[0] = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(extendRef).descriptionAndTooltip(description).create();
}
@@ -825,35 +825,6 @@ public class HighlightClassUtil {
return true;
}
public static boolean hasEnclosingInstanceInScope(PsiClass aClass,
PsiElement scope,
final boolean isSuperClassAccepted,
boolean isTypeParamsAccepted) {
PsiManager manager = aClass.getManager();
PsiElement place = scope;
while (place != null && place != aClass && !(place instanceof PsiFile)) {
if (place instanceof PsiClass) {
if (isSuperClassAccepted) {
if (InheritanceUtil.isInheritorOrSelf((PsiClass)place, aClass, true)) return true;
}
else {
if (manager.areElementsEquivalent(place, aClass)) return true;
}
if (isTypeParamsAccepted && place instanceof PsiTypeParameter) {
return true;
}
}
if (place instanceof PsiModifierListOwner) {
final PsiModifierList modifierList = ((PsiModifierListOwner)place).getModifierList();
if (modifierList != null && modifierList.hasModifierProperty(PsiModifier.STATIC)) {
return false;
}
}
place = place.getParent();
}
return place == aClass;
}
@Nullable
public static HighlightInfo checkCreateInnerClassFromStaticContext(PsiNewExpression expression) {
PsiType type = expression.getType();
@@ -892,7 +863,8 @@ public class HighlightClassUtil {
PsiClass outerClass = aClass.getContainingClass();
if (outerClass == null) return null;
if (outerClass instanceof PsiSyntheticClass || hasEnclosingInstanceInScope(outerClass, placeToSearchEnclosingFrom, true, false)) return null;
if (outerClass instanceof PsiSyntheticClass || InheritanceUtil.hasEnclosingInstanceInScope(outerClass, placeToSearchEnclosingFrom, true,
false)) return null;
return reportIllegalEnclosingUsage(placeToSearchEnclosingFrom, aClass, outerClass, element);
}

View File

@@ -1387,7 +1387,7 @@ public class HighlightUtil extends HighlightUtilBase {
}
if (aClass == null) return null;
if (!HighlightClassUtil.hasEnclosingInstanceInScope(aClass, expr, false, false) &&
if (!InheritanceUtil.hasEnclosingInstanceInScope(aClass, expr, false, false) &&
!resolvesToImmediateSuperInterface(expr, qualifier, aClass)) {
return HighlightClassUtil.reportIllegalEnclosingUsage(expr, null, aClass, expr);
}

View File

@@ -1064,7 +1064,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
final PsiTypeParameterListOwner owner = ((PsiTypeParameter)resolved).getOwner();
if (owner instanceof PsiClass) {
final PsiClass outerClass = (PsiClass)owner;
if (!HighlightClassUtil.hasEnclosingInstanceInScope(outerClass, ref, true, false)) {
if (!InheritanceUtil.hasEnclosingInstanceInScope(outerClass, ref, true, false)) {
myHolder.add(HighlightClassUtil.reportIllegalEnclosingUsage(ref, aClass, (PsiClass)owner, ref));
}
}
@@ -1190,21 +1190,17 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
.descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(expression, resolveResult)).create());
}
}
if (!myHolder.hasErrorResults()) {
final String errorMessage = PsiMethodReferenceUtil.checkMethodReferenceContext(expression);
if (errorMessage != null) {
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(errorMessage).create());
}
}
}
if (!myHolder.hasErrorResults()) {
myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, expression.getTextRange()));
}
if (!myHolder.hasErrorResults()) {
if (method instanceof PsiMethod && ((PsiMethod)method).hasModifierProperty(PsiModifier.ABSTRACT)) {
final PsiElement qualifier = expression.getQualifier();
if (qualifier instanceof PsiSuperExpression) {
myHolder.add(HighlightInfo
.newHighlightInfo(HighlightInfoType.ERROR)
.range(expression.getReferenceNameElement())
.descriptionAndTooltip("Abstract method '" + ((PsiMethod)method).getName() + "' cannot be accessed directly").create());
}
}
}
}
@Override

View File

@@ -20,6 +20,8 @@ import com.intellij.openapi.project.Project;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.util.*;
import com.intellij.util.Function;
import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.tree.TreeInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -34,6 +36,15 @@ public class PsiMethodReferenceUtil {
public static final Logger LOG = Logger.getInstance("#" + PsiMethodReferenceUtil.class.getName());
public static boolean hasReceiver(PsiType[] parameterTypes, QualifierResolveResult qualifierResolveResult, PsiMethodReferenceExpression methodRef) {
if (parameterTypes.length > 0 &&
isReceiverType(parameterTypes[0], qualifierResolveResult.getContainingClass(), qualifierResolveResult.getSubstitutor()) &&
isStaticallyReferenced(methodRef)) {
return true;
}
return false;
}
public static class QualifierResolveResult {
private final PsiClass myContainingClass;
private final PsiSubstitutor mySubstitutor;
@@ -322,9 +333,81 @@ public class PsiMethodReferenceUtil {
private static PsiType getExpandedType(PsiType type, @NotNull PsiElement typeElement) {
if (type instanceof PsiArrayType) {
type = JavaPsiFacade.getElementFactory(typeElement.getProject()).getArrayClassType(((PsiArrayType)type).getComponentType(),
PsiUtil.getLanguageLevel(typeElement));
type = JavaPsiFacade.getElementFactory(typeElement.getProject())
.getArrayClassType(((PsiArrayType)type).getComponentType(), PsiUtil.getLanguageLevel(typeElement));
}
return type;
}
public static String checkMethodReferenceContext(PsiMethodReferenceExpression methodRef) {
final PsiElement resolve = methodRef.resolve();
if (resolve == null) return null;
final PsiClass containingClass = resolve instanceof PsiMethod ? ((PsiMethod)resolve).getContainingClass() : (PsiClass)resolve;
final boolean isStaticSelector = isStaticallyReferenced(methodRef);
final PsiElement qualifier = methodRef.getQualifier();
boolean isMethodStatic = false;
boolean receiverReferenced = false;
boolean isConstructor = true;
if (resolve instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)resolve;
isMethodStatic = method.hasModifierProperty(PsiModifier.STATIC);
isConstructor = method.isConstructor();
final Boolean receiver = hasReceiver(methodRef, method);
if (receiver == null) {
return null; //invalid reference
}
receiverReferenced = receiver;
if (method.hasModifierProperty(PsiModifier.ABSTRACT) && qualifier instanceof PsiSuperExpression) {
return "Abstract method '" + method.getName() + "' cannot be accessed directly";
}
}
if (!receiverReferenced && isStaticSelector && !isMethodStatic && !isConstructor) {
return "Non-static method cannot be referenced from a static context";
}
if (!receiverReferenced && !isStaticSelector && isMethodStatic) {
return "Static method referenced through non-static qualifier";
}
if (receiverReferenced && isStaticSelector && isMethodStatic && !isConstructor) {
return "Static method referenced through receiver";
}
if (isMethodStatic && isStaticSelector && qualifier instanceof PsiTypeElement) {
final PsiJavaCodeReferenceElement referenceElement = PsiTreeUtil.getChildOfType(qualifier, PsiJavaCodeReferenceElement.class);
if (referenceElement != null) {
final PsiReferenceParameterList parameterList = referenceElement.getParameterList();
if (parameterList != null && parameterList.getTypeArguments().length > 0) {
return "Parameterized qualifier on static method reference";
}
}
}
if (isConstructor) {
if (containingClass != null && PsiUtil.isInnerClass(containingClass) && containingClass.isPhysical()) {
PsiClass outerClass = containingClass.getContainingClass();
if (outerClass != null && !InheritanceUtil.hasEnclosingInstanceInScope(outerClass, methodRef, true, false)) {
return "An enclosing instance of type " + PsiFormatUtil.formatClass(outerClass, PsiFormatUtilBase.SHOW_NAME) + " is not in scope";
}
}
}
return null;
}
public static Boolean hasReceiver(@NotNull PsiMethodReferenceExpression methodRef, @NotNull PsiMethod method) {
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(methodRef.getFunctionalInterfaceType());
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
final MethodSignature signature = interfaceMethod != null ? interfaceMethod.getSignature(LambdaUtil.getSubstitutor(interfaceMethod, resolveResult)) : null;
if (signature == null) return null;
final PsiType[] parameterTypes = signature.getParameterTypes();
final QualifierResolveResult qualifierResolveResult = getQualifierResolveResult(methodRef);
return method.getParameterList().getParametersCount() + 1 == parameterTypes.length &&
hasReceiver(parameterTypes, qualifierResolveResult, methodRef);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2013 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.
@@ -128,4 +128,33 @@ public class InheritanceUtil {
}
}
}
public static boolean hasEnclosingInstanceInScope(PsiClass aClass,
PsiElement scope,
final boolean isSuperClassAccepted,
boolean isTypeParamsAccepted) {
PsiManager manager = aClass.getManager();
PsiElement place = scope;
while (place != null && place != aClass && !(place instanceof PsiFile)) {
if (place instanceof PsiClass) {
if (isSuperClassAccepted) {
if (isInheritorOrSelf((PsiClass)place, aClass, true)) return true;
}
else {
if (manager.areElementsEquivalent(place, aClass)) return true;
}
if (isTypeParamsAccepted && place instanceof PsiTypeParameter) {
return true;
}
}
if (place instanceof PsiModifierListOwner) {
final PsiModifierList modifierList = ((PsiModifierListOwner)place).getModifierList();
if (modifierList != null && modifierList.hasModifierProperty(PsiModifier.STATIC)) {
return false;
}
}
place = place.getParent();
}
return place == aClass;
}
}

View File

@@ -41,10 +41,7 @@ import com.intellij.psi.scope.processor.FilterScopeProcessor;
import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.psi.util.*;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
@@ -305,7 +302,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
}
final MethodReferenceConflictResolver conflictResolver =
new MethodReferenceConflictResolver(qualifierResolveResult, signature);
new MethodReferenceConflictResolver(qualifierResolveResult, signature, interfaceMethod != null && interfaceMethod.isVarArgs());
final PsiConflictResolver[] resolvers;
if (signature != null) {
final PsiType[] parameterTypes = signature.getParameterTypes();
@@ -407,17 +404,17 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
}
private class MethodReferenceConflictResolver implements PsiConflictResolver {
private final PsiClass myContainingClass;
private final PsiSubstitutor mySubstitutor;
private final MethodSignature mySignature;
private final boolean myBeginsWithReferenceType;
private final PsiMethodReferenceUtil.QualifierResolveResult myQualifierResolveResult;
private final boolean myFunctionalMethodVarArgs;
private MethodReferenceConflictResolver(PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult,
@Nullable MethodSignature signature) {
myContainingClass = qualifierResolveResult.getContainingClass();
@Nullable MethodSignature signature, boolean varArgs) {
myQualifierResolveResult = qualifierResolveResult;
myFunctionalMethodVarArgs = varArgs;
mySubstitutor = qualifierResolveResult.getSubstitutor();
mySignature = signature;
myBeginsWithReferenceType = qualifierResolveResult.isReferenceTypeQualified();
}
@Nullable
@@ -425,13 +422,9 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
public CandidateInfo resolveConflict(@NotNull List<CandidateInfo> conflicts) {
if (mySignature == null) return null;
boolean hasReceiver = false;
final PsiType[] parameterTypes = mySignature.getParameterTypes();
if (parameterTypes.length > 0 &&
PsiMethodReferenceUtil.isReceiverType(parameterTypes[0], myContainingClass, mySubstitutor) &&
PsiMethodReferenceUtil.isStaticallyReferenced(PsiMethodReferenceExpressionImpl.this)) {
hasReceiver = true;
}
boolean hasReceiver = PsiMethodReferenceUtil.hasReceiver(parameterTypes, myQualifierResolveResult,
PsiMethodReferenceExpressionImpl.this);
final List<CandidateInfo> firstCandidates = new ArrayList<CandidateInfo>();
final List<CandidateInfo> secondCandidates = new ArrayList<CandidateInfo>();
@@ -445,11 +438,8 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
final PsiType[] signatureParameterTypes2 = psiMethod.getSignature(subst).getParameterTypes();
final boolean varArgs = psiMethod.isVarArgs();
final boolean validConstructorRef = psiMethod.isConstructor() && (myContainingClass.getContainingClass() == null || myContainingClass.hasModifierProperty(PsiModifier.STATIC));
final boolean staticOrValidConstructorRef = psiMethod.hasModifierProperty(PsiModifier.STATIC) || validConstructorRef;
if ((parameterTypes.length == signatureParameterTypes2.length || varArgs) &&
(!(myBeginsWithReferenceType ^ staticOrValidConstructorRef) || (psiMethod.isConstructor() && conflict.isStaticsScopeCorrect()))) {
if (parameterTypes.length == signatureParameterTypes2.length || (varArgs && !myFunctionalMethodVarArgs)) {
boolean correct = true;
for (int i = 0; i < parameterTypes.length; i++) {
final PsiType type1 = subst.substitute(GenericsUtil.eliminateWildcards(parameterTypes[i]));
@@ -466,7 +456,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
}
}
if (hasReceiver && parameterTypes.length == signatureParameterTypes2.length + 1 && !staticOrValidConstructorRef) {
if (hasReceiver && parameterTypes.length == signatureParameterTypes2.length + 1) {
boolean correct = true;
for (int i = 0; i < signatureParameterTypes2.length; i++) {
final PsiType type1 = subst.substitute(GenericsUtil.eliminateWildcards(parameterTypes[i + 1]));
@@ -491,7 +481,8 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
conflicts.clear();
}
firstCandidates.addAll(secondCandidates);
conflicts.retainAll(firstCandidates);
conflicts.clear();
conflicts.addAll(firstCandidates);
return null;
}
return !firstCandidates.isEmpty() ? firstCandidates.get(0) : secondCandidates.get(0);
@@ -518,6 +509,11 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
myLanguageLevel);
return conflicts.size() == 1 ? conflicts.get(0) : null;
}
@Override
protected boolean checkSameConflicts(CandidateInfo method, CandidateInfo conflict) {
return method == conflict;
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2013 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,7 +157,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
for (int j = 0; j < i; j++) {
ProgressManager.checkCanceled();
final CandidateInfo conflict = newConflictsArray[j];
assert conflict != method;
if (checkSameConflicts(method, conflict)) continue;
switch (isMoreSpecific(method, conflict, applicabilityLevel, languageLevel)) {
case FIRST:
conflicts.remove(conflict);
@@ -173,6 +173,11 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
}
}
protected boolean checkSameConflicts(CandidateInfo method, CandidateInfo conflict) {
assert method != conflict;
return false;
}
private static void checkAccessStaticLevels(List<CandidateInfo> conflicts, boolean checkAccessible) {
int conflictsCount = conflicts.size();

View File

@@ -10,7 +10,7 @@ class Test {
static abstract class Child extends Parent {
abstract int foo() ;
void test() {
I s = super::<error descr="Abstract method 'foo' cannot be accessed directly">foo</error>;
I s = <error descr="Abstract method 'foo' cannot be accessed directly">super::foo</error>;
I s1 = this::foo;
Parent sup = null;

View File

@@ -29,8 +29,8 @@ class AlienTest {
<error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IInt'">IInt i2 = MyTest::foo;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IInt'">IInt i3 = MyTest::bar;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IIntInt'">IIntInt i4 = MyTest::bar;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IInt'">IInt i5 = MyTest::baz;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IInt'">IInt i6 = MyTest.foo::foo;</error>
IInt i5 = <error descr="Non-static method cannot be referenced from a static context">MyTest::baz</error>;
IInt i6 = <error descr="'foo(int)' is not public in 'MyTest.Foo'. Cannot be accessed from outside package">MyTest.foo::foo</error>;
IInt i7 = MyTest.<error descr="'MyTest.Foo' has private access in 'MyTest'">Foo</error>::foo;
}
}

View File

@@ -16,11 +16,11 @@ class NonStaticInner {
static void call12(I2 s) {}
static {
<error descr="Incompatible types. Found: '<method reference>', required: 'NonStaticInner.I1'">I1 i1 = NonStaticInner.Inner :: new;</error>
call11<error descr="'call11(NonStaticInner.I1)' in 'NonStaticInner' cannot be applied to '(<method reference>)'">(NonStaticInner.Inner :: new)</error>;
I1 i1 = <error descr="An enclosing instance of type NonStaticInner is not in scope">NonStaticInner.Inner :: new</error>;
call11(<error descr="An enclosing instance of type NonStaticInner is not in scope">NonStaticInner.Inner :: new</error>);
<error descr="Incompatible types. Found: '<method reference>', required: 'NonStaticInner.I2'">I2 i2 = NonStaticInner.Inner :: new;</error>
call12<error descr="'call12(NonStaticInner.I2)' in 'NonStaticInner' cannot be applied to '(<method reference>)'">(NonStaticInner.Inner :: new)</error>;
I2 i2 = <error descr="An enclosing instance of type NonStaticInner is not in scope">NonStaticInner.Inner :: new</error>;
call12(<error descr="An enclosing instance of type NonStaticInner is not in scope">NonStaticInner.Inner :: new</error>);
}
}

View File

@@ -68,7 +68,7 @@ class MyTest3 {
static void m() { }
public static void main(String[] args) {
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest3.I'">I s = new MyTest3()::m;</error>
I s = <error descr="Static method referenced through non-static qualifier">new MyTest3()::m</error>;
}
}

View File

@@ -7,7 +7,7 @@ class Test<X> {
void test() {
<error descr="Incompatible types. Found: '<method reference>', required: 'Test.I'">I i1 = Test<String>::foo;</error>
I i1 = <error descr="Parameterized qualifier on static method reference">Test<String>::foo</error>;
I i2 = Test::foo;
}

View File

@@ -41,21 +41,21 @@ class MyTest1 {
static void call2(I2 s) { }
static void test1() {
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest1.I1'">I1 s1 = MyTest1 ::m1;</error>
call1<error descr="'call1(MyTest1.I1)' in 'MyTest1' cannot be applied to '(<method reference>)'">(MyTest1::m1)</error>;
I1 s1 = <error descr="Non-static method cannot be referenced from a static context">MyTest1 ::m1</error>;
call1(<error descr="Non-static method cannot be referenced from a static context">MyTest1::m1</error>);
I1 s2 = MyTest1 :: m2;
call1(MyTest1::m2);
I1 s3 = MyTest1::m3;
call1(MyTest1::m3);
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest1.I1'">I1 s4 = MyTest1::m4;</error>
call1<error descr="'call1(MyTest1.I1)' in 'MyTest1' cannot be applied to '(<method reference>)'">(MyTest1::m4)</error>;
I1 s4 = <error descr="Non-static method cannot be referenced from a static context">MyTest1::m4</error>;
call1(<error descr="Non-static method cannot be referenced from a static context">MyTest1::m4</error>);
}
static void test2() {
I2 s1 = MyTest1 :: m1;
call2(MyTest1::m1);
I2 s2 = MyTest1 :: m2;
call2(MyTest1::m2);
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest1.I2'">I2 s1 = MyTest1 :: m1;</error>
call2<error descr="'call2(MyTest1.I2)' in 'MyTest1' cannot be applied to '(<method reference>)'">(MyTest1::m1)</error>;
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest1.I2'">I2 s2 = MyTest1 :: m2;</error>
call2<error descr="'call2(MyTest1.I2)' in 'MyTest1' cannot be applied to '(<method reference>)'">(MyTest1::m2)</error>;
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest1.I2'">I2 s3 = MyTest1 :: m3;</error>
call2<error descr="'call2(MyTest1.I2)' in 'MyTest1' cannot be applied to '(<method reference>)'">(MyTest1::m3)</error>;
@@ -90,21 +90,21 @@ class MyTest2 {
static void call2(I2 s) { }
static void test1() {
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest2.I1'">I1 s1 = MyTest2 ::m1;</error>
call1<error descr="'call1(MyTest2.I1)' in 'MyTest2' cannot be applied to '(<method reference>)'">(MyTest2::m1)</error>;
I1 s1 = <error descr="Non-static method cannot be referenced from a static context">MyTest2 ::m1</error>;
call1(<error descr="Non-static method cannot be referenced from a static context">MyTest2::m1</error>);
I1 s2 = MyTest2 :: m2;
call1(MyTest2::m2);
I1 s3 = MyTest2::m3;
call1(MyTest2::m3);
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest2.I1'">I1 s4 = MyTest2::m4;</error>
call1<error descr="'call1(MyTest2.I1)' in 'MyTest2' cannot be applied to '(<method reference>)'">(MyTest2::m4)</error>;
I1 s4 = <error descr="Non-static method cannot be referenced from a static context">MyTest2::m4</error>;
call1(<error descr="Non-static method cannot be referenced from a static context">MyTest2::m4</error>);
}
static void test2() {
I2 s1 = MyTest2 :: m1;
call2(MyTest2::m1);
I2 s2 = MyTest2 :: m2;
call2(MyTest2::m2);
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest2.I2'">I2 s1 = MyTest2 :: m1;</error>
call2<error descr="'call2(MyTest2.I2)' in 'MyTest2' cannot be applied to '(<method reference>)'">(MyTest2::m1)</error>;
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest2.I2'">I2 s2 = MyTest2 :: m2;</error>
call2<error descr="'call2(MyTest2.I2)' in 'MyTest2' cannot be applied to '(<method reference>)'">(MyTest2::m2)</error>;
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest2.I2'">I2 s3 = MyTest2 :: m3;</error>
call2<error descr="'call2(MyTest2.I2)' in 'MyTest2' cannot be applied to '(<method reference>)'">(MyTest2::m3)</error>;
@@ -115,10 +115,10 @@ class MyTest2 {
static void call3(I1 s) {}
static void call3(I2 s) {}
static {
call3(MyTest2::m1);
call3<error descr="Ambiguous method call: both 'MyTest2.call3(I1)' and 'MyTest2.call3(I2)' match">(MyTest2::m2)</error>;
call3(<error descr="Non-static method cannot be referenced from a static context">MyTest2::m1</error>);
call3(MyTest2::m2);
call3(MyTest2::m3);
call3<error descr="Cannot resolve method 'call3(<method reference>)'">(MyTest2::m4)</error>;
call3(<error descr="Non-static method cannot be referenced from a static context">MyTest2::m4</error>);
}
}

View File

@@ -7,8 +7,8 @@ class Test<T> {
Test test = new Test<String>();
BlahBlah<String> blahBlah = test::<String>foo;
BlahBlah<String> blahBlah1 = test::<String>foo1;
<error descr="Incompatible types. Found: '<method reference>', required: 'BlahBlah<java.lang.String>'">BlahBlah<String> blahBlah2 = test::<String>foo2;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'BlahBlah<java.lang.String>'">BlahBlah<String> blahBlah3 = test::<String>foo3;</error>
BlahBlah<String> blahBlah2 = <error descr="Static method referenced through non-static qualifier">test::<String>foo2</error>;
BlahBlah<String> blahBlah3 = <error descr="Static method referenced through non-static qualifier">test::<String>foo3</error>;
}
}

View File

@@ -55,7 +55,7 @@ class MyTest {
{
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i_1 = MyTest::_1;</error>
I1 i_1 = <error descr="Non-static method cannot be referenced from a static context">MyTest::_1</error>;
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i_2 = MyTest::_2;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i_3 = MyTest::_3;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i_4 = MyTest::_4;</error>

View File

@@ -2,8 +2,8 @@ import java.util.*;
class Test {
void test() {
Comparator<Test> r2 = Test::yyy;
<error descr="Incompatible types. Found: '<method reference>', required: 'Comparator1<Test>'">Comparator1<Test> c1 = Test::yyy;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'java.util.Comparator<Test>'">Comparator<Test> r2 = Test::yyy;</error>
Comparator1<Test> c1 = <error descr="Non-static method cannot be referenced from a static context">Test::yyy</error>;
<error descr="Incompatible types. Found: '<method reference>', required: 'Comparator1<Test>'">Comparator1<Test> c2 = Test::xxx;</error>
}
int yyy(Test... p) { return 1; }