method refs: inner classes constructors

This commit is contained in:
anna
2012-10-01 12:22:18 +02:00
parent 1cb5f084a1
commit 61ce8c8f12
4 changed files with 93 additions and 10 deletions

View File

@@ -593,7 +593,8 @@ public class LambdaUtil {
if (signatureParameterTypes1.length == signatureParameterTypes2.length + 1) {
final PsiClassType classType = JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass, psiSubstitutor);
final PsiType receiverType = signatureParameterTypes1[0];
if (receiverType.equals(classType) ||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(receiverType);
if (PsiTreeUtil.isAncestor(resolveResult.getElement(), psiClass, false) && resolveResult.getSubstitutor().equals(psiSubstitutor) ||
(receiverType instanceof PsiClassType && ((PsiClassType)receiverType).isRaw() && receiverType.equals(TypeConversionUtil.erasure(classType)))) {
offset++;
}

View File

@@ -237,12 +237,14 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
processor.setName(isConstructor ? containingClass.getName() : element.getText());
if (checkStatic) {
PsiClass aClass = null;
if (PsiTreeUtil.isAncestor(containingClass, PsiMethodReferenceExpressionImpl.this, false)) {
aClass = containingClass;
}
if (PsiUtil.getEnclosingStaticElement(PsiMethodReferenceExpressionImpl.this, aClass) != null) {
processor.handleEvent(JavaScopeProcessorEvent.START_STATIC, null);
if (containingClass.getContainingClass() == null || !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
PsiClass aClass = null;
if (PsiTreeUtil.isAncestor(containingClass, PsiMethodReferenceExpressionImpl.this, false)) {
aClass = containingClass;
}
if (PsiUtil.getEnclosingStaticElement(PsiMethodReferenceExpressionImpl.this, aClass) != null) {
processor.handleEvent(JavaScopeProcessorEvent.START_STATIC, null);
}
}
}
ResolveState state = ResolveState.initial().put(PsiSubstitutor.KEY, substitutor);
@@ -277,7 +279,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
final PsiType[] parameterTypes = mySignature.getParameterTypes();
if (parameterTypes.length > 0) {
final PsiClassType.ClassResolveResult classResolveResult = PsiUtil.resolveGenericsClassInType(parameterTypes[0]);
if (classResolveResult.getElement() == myContainingClass && classResolveResult.getSubstitutor().equals(mySubstitutor)) {
if (PsiTreeUtil.isAncestor(classResolveResult.getElement(), myContainingClass, false) && classResolveResult.getSubstitutor().equals(mySubstitutor)) {
hasReceiver = true;
}
}
@@ -296,7 +298,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
final boolean isStatic = psiMethod.hasModifierProperty(PsiModifier.STATIC);
if ((parameterTypes.length == signatureParameterTypes2.length || varArgs && parameterTypes.length >= signatureParameterTypes2.length) &&
(isStatic || psiMethod.isConstructor())) {
(isStatic || (psiMethod.isConstructor() && (conflict.isStaticsScopeCorrect() || myContainingClass.getContainingClass() == null) && !hasReceiver))) {
boolean correct = true;
for (int i = 0; i < parameterTypes.length; i++) {
final PsiType type1 = parameterTypes[i];
@@ -310,7 +312,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
}
}
if (hasReceiver && parameterTypes.length == signatureParameterTypes2.length + 1 && !isStatic) {
if (hasReceiver && parameterTypes.length == signatureParameterTypes2.length + 1 && !isStatic && (!psiMethod.isConstructor() || myContainingClass.getContainingClass() != null)) {
boolean correct = true;
for (int i = 0; i < signatureParameterTypes2.length; i++) {
final PsiType type1 = parameterTypes[i + 1];

View File

@@ -0,0 +1,76 @@
class NonStaticInner {
class Inner {
Inner(NonStaticInner outer) {}
Inner() {}
}
interface I1 {
Inner m(NonStaticInner rec);
}
interface I2 {
Inner m();
}
static void call11(I1 s) {}
static void call12(I2 s) {}
static {
I1 i1 = NonStaticInner.Inner :: new;
call11(NonStaticInner.Inner :: new);
<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>;
}
}
class StaticInner {
static class Inner {
Inner(StaticInner outer) {}
Inner() {}
}
interface I1 {
Inner m(StaticInner rec);
}
interface I2 {
Inner m();
}
static void call21(I1 s) {}
static void call22(I2 s) {}
static {
I1 i1 = StaticInner.Inner :: new;
call21(StaticInner.Inner :: new);
I2 i2 = StaticInner.Inner :: new;
call22(StaticInner.Inner :: new);
}
}
class StaticInner1 {
static class Inner {
Inner(StaticInner outer) {}
Inner() {}
}
interface I1 {
Inner _(StaticInner rec);
}
interface I2 {
Inner _();
}
static void call3(I1 s) {}
static void call3(I2 s) {}
static {
call3<error descr="Cannot resolve method 'call3(<method reference>)'">(StaticInner.Inner :: new)</error>;
}
}

View File

@@ -56,6 +56,10 @@ public class MethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testConstructorRefs() throws Exception {
doTest();
}
public void testConstructorRefsInnerClasses() throws Exception {
doTest();
}
public void testVarargs() throws Exception {
doTest();