method refs: default constructors check (IDEA-92777)

This commit is contained in:
anna
2012-10-11 18:32:47 +02:00
parent 79354743ae
commit 56036f1542
2 changed files with 34 additions and 24 deletions
@@ -254,6 +254,20 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
}
}
private boolean isLocatedInStaticContext(PsiClass containingClass) {
final PsiClass gContainingClass = containingClass.getContainingClass();
if (gContainingClass == null || !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
PsiClass aClass = null;
if (PsiTreeUtil.isAncestor(gContainingClass != null ? gContainingClass : containingClass, this, false)) {
aClass = gContainingClass != null ? gContainingClass : containingClass;
}
if (PsiUtil.getEnclosingStaticElement(this, aClass) != null) {
return true;
}
}
return false;
}
private class MethodReferenceResolver implements ResolveCache.PolyVariantResolver<PsiJavaReference> {
@NotNull
@Override
@@ -300,21 +314,9 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
if (parameterTypes.length == 1 && LambdaUtil.isReceiverType(parameterTypes[0], containingClass, substitutor)) {
hasReceiver = true;
}
boolean insideStaticClass = containingClass.getContainingClass() == null;
if (!insideStaticClass) { //inner class
PsiClass parentClass = containingClass;
while (parentClass != null) {
if (parentClass.hasModifierProperty(PsiModifier.STATIC)) {
insideStaticClass = true;
break;
}
parentClass = parentClass.getContainingClass();
}
}
final boolean innerClassOuterClassReference = containingClass.getContainingClass() != null && !containingClass.hasModifierProperty(PsiModifier.STATIC);
ClassCandidateInfo candidateInfo = null;
if (insideStaticClass && parameterTypes.length == 0 || hasReceiver && innerClassOuterClassReference) {
if (!isLocatedInStaticContext(containingClass) && parameterTypes.length == 0 || hasReceiver && innerClassOuterClassReference) {
candidateInfo = new ClassCandidateInfo(containingClass, substitutor);
}
return candidateInfo == null ? JavaResolveResult.EMPTY_ARRAY : new JavaResolveResult[]{candidateInfo};
@@ -356,17 +358,8 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
processor.setAccessClass(containingClass);
}
if (beginsWithReferenceType) {
final PsiClass gContainingClass = containingClass.getContainingClass();
if (gContainingClass == null || !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
PsiClass aClass = null;
if (PsiTreeUtil.isAncestor(gContainingClass != null ? gContainingClass : containingClass, PsiMethodReferenceExpressionImpl.this, false)) {
aClass = gContainingClass != null ? gContainingClass : containingClass;
}
if (PsiUtil.getEnclosingStaticElement(PsiMethodReferenceExpressionImpl.this, aClass) != null) {
processor.handleEvent(JavaScopeProcessorEvent.START_STATIC, null);
}
}
if (beginsWithReferenceType && isLocatedInStaticContext(containingClass)) {
processor.handleEvent(JavaScopeProcessorEvent.START_STATIC, null);
}
ResolveState state = ResolveState.initial().put(PsiSubstitutor.KEY, substitutor);
containingClass.processDeclarations(processor, state,
@@ -86,3 +86,20 @@ class DefaultConstructor4 {
StaticInner foo(DefaultConstructor4 receiver);
}
}
class DefaultConstructor5 {
public class Inner {}
static void test() {
<error descr="Incompatible types. Found: '<method reference>', required: 'DefaultConstructor5.I'">I i = Inner::new;</error>
}
void test1() {
I i = Inner::new;
}
interface I {
DefaultConstructor5.Inner foo();
}
}