mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -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.
|
||||
@@ -754,8 +754,13 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
|
||||
@Override public void visitTryStatement(PsiTryStatement statement) {
|
||||
startElement(statement);
|
||||
PsiCodeBlock finallyBlock = statement.getFinallyBlock();
|
||||
|
||||
PsiResourceList resourceList = statement.getResourceList();
|
||||
if (resourceList != null) {
|
||||
resourceList.accept(this);
|
||||
}
|
||||
|
||||
PsiCodeBlock finallyBlock = statement.getFinallyBlock();
|
||||
if (finallyBlock != null) {
|
||||
myCatchStack.push(new CatchDescriptor(finallyBlock));
|
||||
}
|
||||
@@ -817,6 +822,21 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
if (catchBlock != null) catchBlock.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitResourceList(PsiResourceList resourceList) {
|
||||
startElement(resourceList);
|
||||
|
||||
List<PsiResourceVariable> variables = resourceList.getResourceVariables();
|
||||
for (PsiResourceVariable variable : variables) {
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
if (initializer != null) {
|
||||
initializeVariable(variable, initializer);
|
||||
}
|
||||
}
|
||||
|
||||
finishElement(resourceList);
|
||||
}
|
||||
|
||||
@Override public void visitWhileStatement(PsiWhileStatement statement) {
|
||||
startElement(statement);
|
||||
|
||||
|
||||
@@ -589,7 +589,10 @@ public class LambdaUtil {
|
||||
methodReferenceExpression.process(classRef, substRef);
|
||||
|
||||
final MethodSignature signature1 = method.getSignature(resolveResult.getSubstitutor());
|
||||
final MethodSignature signature2 = ((PsiMethod)resolve).getSignature(substRef.get());
|
||||
PsiSubstitutor subst = PsiSubstitutor.EMPTY;
|
||||
subst = subst.putAll(result.getSubstitutor());
|
||||
subst = subst.putAll(substRef.get());
|
||||
final MethodSignature signature2 = ((PsiMethod)resolve).getSignature(subst);
|
||||
if (areAcceptable(signature1, signature2, classRef.get(), substRef.get(), ((PsiMethod)resolve).isVarArgs())) return true;
|
||||
}
|
||||
}
|
||||
@@ -636,7 +639,7 @@ public class LambdaUtil {
|
||||
for (int i = 0; i < min; i++) {
|
||||
final PsiType type1 = signatureParameterTypes1[offset + i];
|
||||
final PsiType type2 = isVarargs && i == min - 1 ? ((PsiArrayType)signatureParameterTypes2[i]).getComponentType() : signatureParameterTypes2[i];
|
||||
if (!GenericsUtil.eliminateWildcards(psiSubstitutor.substitute(type1)).equals(GenericsUtil.eliminateWildcards(type2))) {
|
||||
if (!TypeConversionUtil.isAssignable(type2, psiSubstitutor.substitute(GenericsUtil.eliminateWildcards(type1)))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -797,6 +797,21 @@ public class TypeConversionUtil {
|
||||
}
|
||||
|
||||
public static boolean boxingConversionApplicable(final PsiType left, final PsiType right) {
|
||||
if (right instanceof PsiMethodReferenceType) {
|
||||
final JavaResolveResult result = ((PsiMethodReferenceType)right).getExpression().advancedResolve(false);
|
||||
PsiElement element = result.getElement();
|
||||
final PsiClassType.ClassResolveResult functionalInterfaceResult = PsiUtil.resolveGenericsClassInType(left);
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceResult);
|
||||
if (element instanceof PsiMethod && interfaceMethod != null) {
|
||||
final PsiType[] parameterTypes = ((PsiMethod)element).getSignature(result.getSubstitutor()).getParameterTypes();
|
||||
final PsiType[] argTypes = interfaceMethod.getSignature(functionalInterfaceResult.getSubstitutor()).getParameterTypes();
|
||||
if (parameterTypes.length != argTypes.length) return false;
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
if (boxingConversionApplicable(parameterTypes[i], argTypes[i])) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (left instanceof PsiPrimitiveType && !PsiType.NULL.equals(left)) {
|
||||
return right instanceof PsiClassType && isAssignable(left, right);
|
||||
}
|
||||
|
||||
+76
-16
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiManagerEx;
|
||||
import com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy;
|
||||
import com.intellij.psi.impl.source.resolve.ResolveCache;
|
||||
import com.intellij.psi.impl.source.tree.ChildRole;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
@@ -30,6 +31,7 @@ import com.intellij.psi.scope.ElementClassFilter;
|
||||
import com.intellij.psi.scope.JavaScopeProcessorEvent;
|
||||
import com.intellij.psi.scope.PsiConflictResolver;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.scope.conflictResolvers.JavaMethodsConflictResolver;
|
||||
import com.intellij.psi.scope.processor.FilterScopeProcessor;
|
||||
import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
@@ -37,6 +39,7 @@ 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.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -220,7 +223,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
public ResolveResult[] resolve(@NotNull PsiJavaReference reference, boolean incompleteCode) {
|
||||
final Ref<PsiClass> classRef = new Ref<PsiClass>();
|
||||
final Ref<PsiSubstitutor> substRef = new Ref<PsiSubstitutor>();
|
||||
boolean checkStatic = process(classRef, substRef);
|
||||
final boolean beginsWithReferenceType = process(classRef, substRef);
|
||||
|
||||
final PsiClass containingClass = classRef.get();
|
||||
final PsiSubstitutor substitutor = substRef.get();
|
||||
@@ -242,15 +245,59 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
|
||||
final MethodSignature signature = interfaceMethod != null ? interfaceMethod.getSignature(resolveResult.getSubstitutor()) : null;
|
||||
final MethodReferenceConflictResolver conflictResolver = new MethodReferenceConflictResolver(containingClass, substitutor,
|
||||
signature);
|
||||
final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(PsiMethodReferenceExpressionImpl.this,
|
||||
new PsiConflictResolver[]{conflictResolver},
|
||||
new SmartList<CandidateInfo>());
|
||||
final MethodReferenceConflictResolver conflictResolver =
|
||||
new MethodReferenceConflictResolver(containingClass, substitutor, signature, beginsWithReferenceType);
|
||||
final PsiConflictResolver[] resolvers;
|
||||
if (signature != null) {
|
||||
final PsiType[] parameterTypes = signature.getParameterTypes();
|
||||
resolvers = new PsiConflictResolver[]{conflictResolver,
|
||||
new JavaMethodsConflictResolver(PsiMethodReferenceExpressionImpl.this, parameterTypes) {
|
||||
@Override
|
||||
public CandidateInfo resolveConflict(List<CandidateInfo> conflicts) {
|
||||
boolean varargs = false;
|
||||
for (CandidateInfo conflict : conflicts) {
|
||||
final PsiElement psiElement = conflict.getElement();
|
||||
if (psiElement instanceof PsiMethod && ((PsiMethod)psiElement).isVarArgs()) {
|
||||
varargs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
checkSpecifics(conflicts, varargs ? MethodCandidateInfo.ApplicabilityLevel.VARARGS : MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY);
|
||||
return conflicts.size() == 1 ? conflicts.get(0) : null;
|
||||
}
|
||||
}};
|
||||
}
|
||||
else {
|
||||
resolvers = new PsiConflictResolver[]{conflictResolver};
|
||||
}
|
||||
final MethodCandidatesProcessor processor =
|
||||
new MethodCandidatesProcessor(PsiMethodReferenceExpressionImpl.this, resolvers, new SmartList<CandidateInfo>()) {
|
||||
@Override
|
||||
protected MethodCandidateInfo createCandidateInfo(final PsiMethod method,
|
||||
PsiSubstitutor substitutor,
|
||||
boolean staticProblem,
|
||||
boolean accessible) {
|
||||
final PsiExpressionList argumentList = getArgumentList();
|
||||
return new MethodCandidateInfo(method, substitutor, !accessible, staticProblem, argumentList, myCurrentFileContext,
|
||||
argumentList != null ? argumentList.getExpressionTypes() : null, getTypeArguments(),
|
||||
getLanguageLevel()) {
|
||||
@Override
|
||||
public PsiSubstitutor inferTypeArguments(ParameterTypeInferencePolicy policy) {
|
||||
if (signature == null) return PsiSubstitutor.EMPTY;
|
||||
final PsiType[] types = method.getSignature(PsiSubstitutor.EMPTY).getParameterTypes();
|
||||
final PsiType[] rightTypes = signature.getParameterTypes();
|
||||
if (types.length != rightTypes.length) return PsiSubstitutor.EMPTY;
|
||||
return JavaPsiFacade.getInstance(getProject()).getResolveHelper()
|
||||
.inferTypeArguments(method.getTypeParameters(), types, rightTypes,
|
||||
PsiUtil.getLanguageLevel(PsiMethodReferenceExpressionImpl.this));
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
processor.setIsConstructor(isConstructor);
|
||||
processor.setName(isConstructor ? containingClass.getName() : element.getText());
|
||||
|
||||
if (checkStatic) {
|
||||
if (beginsWithReferenceType) {
|
||||
if (containingClass.getContainingClass() == null || !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
PsiClass aClass = null;
|
||||
if (PsiTreeUtil.isAncestor(containingClass, PsiMethodReferenceExpressionImpl.this, false)) {
|
||||
@@ -275,13 +322,15 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
private final PsiClass myContainingClass;
|
||||
private final PsiSubstitutor mySubstitutor;
|
||||
private final MethodSignature mySignature;
|
||||
private final boolean myBeginsWithReferenceType;
|
||||
|
||||
private MethodReferenceConflictResolver(PsiClass containingClass,
|
||||
PsiSubstitutor psiSubstitutor,
|
||||
@Nullable MethodSignature signature) {
|
||||
@Nullable MethodSignature signature, boolean beginsWithReferenceType) {
|
||||
myContainingClass = containingClass;
|
||||
mySubstitutor = psiSubstitutor;
|
||||
mySignature = signature;
|
||||
myBeginsWithReferenceType = beginsWithReferenceType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -293,7 +342,8 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
final PsiType[] parameterTypes = mySignature.getParameterTypes();
|
||||
if (parameterTypes.length > 0) {
|
||||
final PsiClassType.ClassResolveResult classResolveResult = PsiUtil.resolveGenericsClassInType(parameterTypes[0]);
|
||||
if (LambdaUtil.isReceiverType(parameterTypes[0], myContainingClass) && classResolveResult.getSubstitutor().equals(mySubstitutor)) {
|
||||
if (LambdaUtil.isReceiverType(parameterTypes[0], myContainingClass) &&
|
||||
((parameterTypes[0] instanceof PsiClassType && ((PsiClassType)parameterTypes[0]).isRaw()) || classResolveResult.getSubstitutor().equals(mySubstitutor))) {
|
||||
hasReceiver = true;
|
||||
}
|
||||
}
|
||||
@@ -305,33 +355,35 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
final PsiMethod psiMethod = ((MethodCandidateInfo)conflict).getElement();
|
||||
if (psiMethod == null) continue;
|
||||
PsiSubstitutor subst = PsiSubstitutor.EMPTY;
|
||||
subst = subst.putAll(conflict.getSubstitutor());
|
||||
subst = subst.putAll(mySubstitutor);
|
||||
final PsiType[] signatureParameterTypes2 = psiMethod.getSignature(subst).getParameterTypes();
|
||||
|
||||
final boolean varArgs = psiMethod.isVarArgs();
|
||||
final boolean isStatic = psiMethod.hasModifierProperty(PsiModifier.STATIC);
|
||||
|
||||
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 && parameterTypes.length >= signatureParameterTypes2.length) &&
|
||||
(isStatic || (psiMethod.isConstructor() && (conflict.isStaticsScopeCorrect() || myContainingClass.getContainingClass() == null) && !hasReceiver))) {
|
||||
(!myBeginsWithReferenceType || staticOrValidConstructorRef)) {
|
||||
boolean correct = true;
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
final PsiType type1 = parameterTypes[i];
|
||||
final PsiType type2 = varArgs && i >= signatureParameterTypes2.length - 1 ?
|
||||
((PsiArrayType)signatureParameterTypes2[signatureParameterTypes2.length -1]).getComponentType() :
|
||||
signatureParameterTypes2[i];
|
||||
correct &= GenericsUtil.eliminateWildcards(subst.substitute(type1)).equals(GenericsUtil.eliminateWildcards(type2));
|
||||
correct &= TypeConversionUtil.isAssignable(type2, subst.substitute(GenericsUtil.eliminateWildcards(type1)));
|
||||
}
|
||||
if (correct) {
|
||||
firstCandidates.add(conflict);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasReceiver && parameterTypes.length == signatureParameterTypes2.length + 1 && !isStatic && (!psiMethod.isConstructor() || myContainingClass.getContainingClass() != null)) {
|
||||
if (hasReceiver && parameterTypes.length == signatureParameterTypes2.length + 1 && !staticOrValidConstructorRef) {
|
||||
boolean correct = true;
|
||||
for (int i = 0; i < signatureParameterTypes2.length; i++) {
|
||||
final PsiType type1 = parameterTypes[i + 1];
|
||||
final PsiType type2 = signatureParameterTypes2[i];
|
||||
correct &= GenericsUtil.eliminateWildcards(subst.substitute(type1)).equals(GenericsUtil.eliminateWildcards(type2));
|
||||
correct &= TypeConversionUtil.isAssignable(type2, subst.substitute(GenericsUtil.eliminateWildcards(type1)));
|
||||
}
|
||||
if (correct) {
|
||||
secondCandidates.add(conflict);
|
||||
@@ -339,7 +391,15 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
}
|
||||
}
|
||||
|
||||
if (secondCandidates.size() + firstCandidates.size() != 1) return null;
|
||||
final int acceptedCount = secondCandidates.size() + firstCandidates.size();
|
||||
if (acceptedCount != 1) {
|
||||
if (acceptedCount == 0) {
|
||||
conflicts.clear();
|
||||
}
|
||||
firstCandidates.addAll(secondCandidates);
|
||||
conflicts.retainAll(firstCandidates);
|
||||
return null;
|
||||
}
|
||||
return !firstCandidates.isEmpty() ? firstCandidates.get(0) : secondCandidates.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -128,7 +128,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
}
|
||||
}
|
||||
|
||||
private void checkSpecifics(List<CandidateInfo> conflicts, @MethodCandidateInfo.ApplicabilityLevelConstant int applicabilityLevel) {
|
||||
public void checkSpecifics(List<CandidateInfo> conflicts, @MethodCandidateInfo.ApplicabilityLevelConstant int applicabilityLevel) {
|
||||
final boolean applicable = applicabilityLevel > MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE;
|
||||
|
||||
int conflictsCount = conflicts.size();
|
||||
@@ -450,7 +450,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
PsiType type1 = params1[Math.min(i, params1.length - 1)].getType();
|
||||
PsiType type2 = params2[Math.min(i, params2.length - 1)].getType();
|
||||
if (applicabilityLevel == MethodCandidateInfo.ApplicabilityLevel.VARARGS) {
|
||||
if (type1 instanceof PsiEllipsisType && type2 instanceof PsiEllipsisType) {
|
||||
if (type1 instanceof PsiEllipsisType && type2 instanceof PsiEllipsisType &&
|
||||
(((PsiArrayType)type1).getComponentType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT) || ((PsiArrayType)type2).getComponentType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT))) {
|
||||
type1 = ((PsiEllipsisType)type1).toArrayType();
|
||||
type2 = ((PsiEllipsisType)type2).toArrayType();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import java.util.Set;
|
||||
|
||||
public class Foo {
|
||||
void foo(Set<String> set) {
|
||||
set.ad<caret>x
|
||||
}
|
||||
}
|
||||
+17
-2
@@ -1,5 +1,3 @@
|
||||
import java.lang.Exception;
|
||||
|
||||
class C {
|
||||
static class MyResource implements AutoCloseable {
|
||||
@Override public void close() { }
|
||||
@@ -25,4 +23,21 @@ class C {
|
||||
System.out.println(r);
|
||||
}
|
||||
}
|
||||
|
||||
interface MyResourceProvider {
|
||||
MyResource getResource();
|
||||
}
|
||||
|
||||
void m3() throws Exception {
|
||||
MyResourceProvider provider = null;
|
||||
try (MyResource r = <warning descr="Method invocation 'provider.getResource()' may produce 'java.lang.NullPointerException'">provider.getResource()</warning>) {
|
||||
System.out.println(r);
|
||||
}
|
||||
}
|
||||
|
||||
void m4() {
|
||||
try (MyResource r = null) {
|
||||
System.out.println(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-1
@@ -21,4 +21,12 @@ abstract class A {
|
||||
{
|
||||
foo<error descr="Ambiguous method call: both 'A.foo(Object...)' and 'A.foo(int...)' match">(1)</error>;
|
||||
}
|
||||
}
|
||||
}
|
||||
abstract class A1 {
|
||||
abstract void foo(double ... x);
|
||||
abstract void foo(int... x);
|
||||
|
||||
{
|
||||
foo(1);
|
||||
}
|
||||
}
|
||||
|
||||
+42
@@ -73,4 +73,46 @@ class StaticInner1 {
|
||||
static {
|
||||
call3<error descr="Ambiguous method call: both 'StaticInner1.call3(I1)' and 'StaticInner1.call3(I2)' match">(StaticInner1.Inner :: new)</error>;
|
||||
}
|
||||
}
|
||||
|
||||
class StaticInner2 {
|
||||
|
||||
static class Inner {
|
||||
Inner() {}
|
||||
}
|
||||
|
||||
|
||||
interface I1 {
|
||||
Inner m(StaticInner2 rec);
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'StaticInner2.I1'">I1 i1 = StaticInner2.Inner :: new;</error>
|
||||
}
|
||||
|
||||
{
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'StaticInner2.I1'">I1 i1 = StaticInner2.Inner :: new;</error>
|
||||
}
|
||||
}
|
||||
|
||||
class NonStaticInner2 {
|
||||
|
||||
class Inner {
|
||||
Inner() {}
|
||||
}
|
||||
|
||||
|
||||
interface I1 {
|
||||
Inner m(NonStaticInner2 rec);
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
I1 i1 = NonStaticInner2.Inner :: new;
|
||||
}
|
||||
|
||||
{
|
||||
I1 i1 = NonStaticInner2.Inner :: new;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -54,7 +54,7 @@ class MyTest2 {
|
||||
static void call(Integer i, I s) { }
|
||||
|
||||
static void test() {
|
||||
call<error descr="Cannot resolve method 'call(int, <method reference>)'">(1, MyTest2::m)</error>; //ambiguous
|
||||
call<error descr="Ambiguous method call: both 'MyTest2.call(int, I)' and 'MyTest2.call(Integer, I)' match">(1, MyTest2::m)</error>; //ambiguous
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
class MyTest {
|
||||
interface I1 {
|
||||
void m(String s);
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
void m(Integer s);
|
||||
}
|
||||
|
||||
interface I3 {
|
||||
void m(Object o);
|
||||
}
|
||||
|
||||
static <T extends Number> void m(T p) {}
|
||||
|
||||
static <T1> void m1(T1 fx) { }
|
||||
|
||||
static void foo(I1 i) {}
|
||||
static void foo(I2 i) {} //m
|
||||
static void foo(I3 i) {}
|
||||
|
||||
static {
|
||||
foo(MyTest::m);
|
||||
foo<error descr="Ambiguous method call: both 'MyTest.foo(I2)' and 'MyTest.foo(I3)' match">(MyTest::m1)</error>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MyTest1 {
|
||||
interface I1 {
|
||||
void m(Integer s);
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
void m(Integer s);
|
||||
}
|
||||
|
||||
static <T extends Number> void m(T p) { }
|
||||
static <T> void m1(T p) { }
|
||||
|
||||
static void foo1(I1 i) { }
|
||||
static void foo2(I1 i) { }
|
||||
static void foo2(I2 i) { }
|
||||
|
||||
static {
|
||||
foo1(MyTest1::m);
|
||||
foo2<error descr="Ambiguous method call: both 'MyTest1.foo2(I1)' and 'MyTest1.foo2(I2)' match">(MyTest1::m)</error>;
|
||||
|
||||
foo1(MyTest1::m1);
|
||||
foo2<error descr="Ambiguous method call: both 'MyTest1.foo2(I1)' and 'MyTest1.foo2(I2)' match">(MyTest1::m1)</error>;
|
||||
}
|
||||
}
|
||||
+59
-7
@@ -1,6 +1,5 @@
|
||||
class MethodReference27 {
|
||||
|
||||
interface SAM {
|
||||
class MyTest1 {
|
||||
interface I {
|
||||
void m(int i1, int i2);
|
||||
}
|
||||
|
||||
@@ -13,10 +12,63 @@ class MethodReference27 {
|
||||
static void m2(int... is) { }
|
||||
static void m2(double... ds) {}
|
||||
|
||||
static void m3(int... is) { }
|
||||
static void m3(Object... ds) {}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SAM s1 = MethodReference27::m1;
|
||||
s1.m(42,42);
|
||||
SAM s2 = MethodReference27 :: m2;
|
||||
s2.m(42,42);
|
||||
I i1 = MyTest1::m1;
|
||||
i1.m(42,42);
|
||||
|
||||
I i2 = MyTest1 :: m2;
|
||||
i2.m(42,42);
|
||||
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest1.I'">I i3 = MyTest1 :: m3;</error>
|
||||
}
|
||||
}
|
||||
|
||||
class MyTest {
|
||||
|
||||
interface I1 {
|
||||
void m(int i);
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
void m(MyTest t, int i);
|
||||
}
|
||||
|
||||
static void static_1(Integer i) {}
|
||||
static void static_2(Integer i1, Integer i2) {}
|
||||
static void static_3(String s) {}
|
||||
static void static_4(String... ss) {}
|
||||
|
||||
void _1(Integer i) {}
|
||||
void _2(Integer i1, Integer i2) {}
|
||||
void _3(String s) {}
|
||||
void _4(String... ss) {}
|
||||
|
||||
static {
|
||||
I1 i1 = MyTest::static_1;
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i2 = MyTest::static_2;</error>
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i3 = MyTest::static_3;</error>
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i4 = MyTest::static_4;</error>
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i_1 = 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>
|
||||
|
||||
I1 i1 = this::_1;
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i2 = this::_2;</error>
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i3 = this::_3;</error>
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I1'">I1 i4 = this::_4;</error>
|
||||
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I2'">I2 i21 = MyTest::m1;</error>
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I2'">I2 i22 = MyTest::m2;</error>
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I2'">I2 i23 = MyTest::m3;</error>
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest.I2'">I2 i24 = MyTest::m4;</error>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
@@ -453,4 +453,14 @@ import java.lang.annotation.Target;
|
||||
assert lookup.items[1].object instanceof PsiMethod
|
||||
}
|
||||
|
||||
public void testPreselectLastChosen() {
|
||||
checkPreferredItems(0, 'add', 'addAll')
|
||||
for (i in 0..10) {
|
||||
incUseCount(lookup, 1)
|
||||
}
|
||||
assertPreferredItems 1, 'add', 'addAll'
|
||||
incUseCount(lookup, 0)
|
||||
assertPreferredItems 0, 'add', 'addAll'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -20,6 +20,7 @@ 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.dataFlow.DataFlowInspection;
|
||||
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
|
||||
import com.intellij.codeInspection.defUse.DefUseInspection;
|
||||
import com.intellij.codeInspection.redundantCast.RedundantCastInspection;
|
||||
@@ -146,7 +147,7 @@ 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 { doTest(true, false, new DefUseInspection()); }
|
||||
public void testTryWithResourcesWarn() throws Exception { doTest(true, false, new DefUseInspection(), new DataFlowInspection()); }
|
||||
public void testSafeVarargsApplicability() throws Exception { doTest(true, false); }
|
||||
public void testUncheckedGenericsArrayCreation() throws Exception { doTest(true, false); }
|
||||
public void testPreciseRethrow() throws Exception { doTest(false, false); }
|
||||
|
||||
+5
-1
@@ -40,7 +40,11 @@ public class MethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testMethodRefMisc() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
|
||||
public void testMethodTypeParamsInference() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testMethodRefMisc1() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@@ -51,15 +51,17 @@ public class StatisticsWeigher extends CompletionWeigher {
|
||||
|
||||
@Override
|
||||
public Integer weigh(@NotNull LookupElement item) {
|
||||
final StatisticsInfo info = getBaseStatisticsInfo(item, myLocation);
|
||||
if (info == StatisticsInfo.EMPTY) {
|
||||
final StatisticsInfo baseInfo = getBaseStatisticsInfo(item, myLocation);
|
||||
if (baseInfo == StatisticsInfo.EMPTY) {
|
||||
return 0;
|
||||
}
|
||||
int max = 0;
|
||||
for (StatisticsInfo statisticsInfo : composeStatsWithPrefix(info, myLocation.getCompletionParameters().getLookup().itemPattern(item))) {
|
||||
max = Math.max(max, ourStatManager.getUseCount(statisticsInfo));
|
||||
int maxUseCount = 0;
|
||||
int minRecency = Integer.MAX_VALUE;
|
||||
for (StatisticsInfo eachInfo : composeStatsWithPrefix(baseInfo, myLocation.getCompletionParameters().getLookup().itemPattern(item))) {
|
||||
maxUseCount = Math.max(maxUseCount, ourStatManager.getUseCount(eachInfo));
|
||||
minRecency = Math.min(minRecency, ourStatManager.getLastUseRecency(eachInfo));
|
||||
}
|
||||
return max;
|
||||
return minRecency == Integer.MAX_VALUE ? maxUseCount : 100 - minRecency;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ public abstract class StatisticsManager implements SettingsSavingComponent {
|
||||
}
|
||||
|
||||
public abstract int getUseCount(@NotNull StatisticsInfo info);
|
||||
public abstract int getLastUseRecency(@NotNull StatisticsInfo info);
|
||||
public abstract void incUseCount(@NotNull StatisticsInfo info);
|
||||
|
||||
public <T,Loc> int getUseCount(final Key<? extends Statistician<T, Loc>> key, final T element, final Loc location) {
|
||||
|
||||
+12
@@ -58,6 +58,18 @@ public class StatisticsManagerImpl extends StatisticsManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLastUseRecency(@NotNull StatisticsInfo info) {
|
||||
if (info == StatisticsInfo.EMPTY) return 0;
|
||||
|
||||
String key1 = info.getContext();
|
||||
int unitNumber = getUnitNumber(key1);
|
||||
synchronized (LOCK) {
|
||||
StatisticsUnit unit = getUnit(unitNumber);
|
||||
return unit.getRecency(key1, info.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void incUseCount(@NotNull final StatisticsInfo info) {
|
||||
if (info == StatisticsInfo.EMPTY) return;
|
||||
if (ApplicationManager.getApplication().isUnitTestMode() && !myTestingStatistics) {
|
||||
|
||||
@@ -33,6 +33,14 @@ class StatisticsUnit {
|
||||
myNumber = number;
|
||||
}
|
||||
|
||||
public int getRecency(String key1, String key2) {
|
||||
final List<String> list = myDataMap.get(key1);
|
||||
if (list == null) return Integer.MAX_VALUE;
|
||||
|
||||
int i = list.indexOf(key2);
|
||||
return i >= 0 ? i : Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public int getData(String key1, String key2) {
|
||||
final List<String> list = myDataMap.get(key1);
|
||||
if (list == null) return 0;
|
||||
|
||||
@@ -143,15 +143,16 @@ public class Configuration implements PersistentStateComponent<Element>, Modific
|
||||
return super.getModificationCount() + myParentConfiguration.getModificationCount();
|
||||
}
|
||||
|
||||
public boolean replaceInjections(final List<? extends BaseInjection> newInjections,
|
||||
final List<? extends BaseInjection> originalInjections) {
|
||||
if (!originalInjections.isEmpty()) {
|
||||
if (myParentConfiguration.replaceInjections(Collections.<BaseInjection>emptyList(), originalInjections)) {
|
||||
myParentConfiguration.replaceInjections(newInjections, Collections.<BaseInjection>emptyList());
|
||||
public boolean replaceInjections(List<? extends BaseInjection> newInjections,
|
||||
List<? extends BaseInjection> originalInjections,
|
||||
boolean forceLevel) {
|
||||
if (!forceLevel && !originalInjections.isEmpty()) {
|
||||
if (myParentConfiguration.replaceInjections(Collections.<BaseInjection>emptyList(), originalInjections, forceLevel)) {
|
||||
myParentConfiguration.replaceInjections(newInjections, Collections.<BaseInjection>emptyList(), forceLevel);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.replaceInjections(newInjections, originalInjections);
|
||||
return super.replaceInjections(newInjections, originalInjections, forceLevel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,7 +390,7 @@ public class Configuration implements PersistentStateComponent<Element>, Modific
|
||||
importInjections(getInjections(supportId), importingInjections, originalInjections, newInjections);
|
||||
}
|
||||
if (!newInjections.isEmpty()) configurationModified();
|
||||
replaceInjections(newInjections, originalInjections);
|
||||
replaceInjections(newInjections, originalInjections, true);
|
||||
return newInjections.size();
|
||||
}
|
||||
|
||||
@@ -505,7 +506,7 @@ public class Configuration implements PersistentStateComponent<Element>, Modific
|
||||
}
|
||||
|
||||
protected void replaceInjectionsWithUndoInner(final List<? extends BaseInjection> add, final List<? extends BaseInjection> remove) {
|
||||
replaceInjections(add, remove);
|
||||
replaceInjections(add, remove, false);
|
||||
}
|
||||
|
||||
public static <T> void replaceInjectionsWithUndo(final Project project, final T add, final T remove,
|
||||
@@ -541,8 +542,9 @@ public class Configuration implements PersistentStateComponent<Element>, Modific
|
||||
}.execute();
|
||||
}
|
||||
|
||||
public boolean replaceInjections(final List<? extends BaseInjection> newInjections,
|
||||
final List<? extends BaseInjection> originalInjections) {
|
||||
public boolean replaceInjections(List<? extends BaseInjection> newInjections,
|
||||
List<? extends BaseInjection> originalInjections,
|
||||
boolean forceLevel) {
|
||||
boolean changed = false;
|
||||
for (BaseInjection injection : originalInjections) {
|
||||
changed |= myInjections.get(injection.getSupportId()).remove(injection);
|
||||
|
||||
@@ -882,7 +882,7 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, NonD
|
||||
|
||||
public void apply() {
|
||||
final List<BaseInjection> injectionList = getInjectionList(injectionInfos);
|
||||
cfg.replaceInjections(injectionList, originalInjections);
|
||||
cfg.replaceInjections(injectionList, originalInjections, true);
|
||||
originalInjections.clear();
|
||||
originalInjections.addAll(injectionList);
|
||||
sortInjections(originalInjections);
|
||||
|
||||
@@ -108015,6 +108015,7 @@ receivership
|
||||
receivership's
|
||||
receives
|
||||
receiving
|
||||
recency
|
||||
recension
|
||||
recension's
|
||||
recent
|
||||
|
||||
Reference in New Issue
Block a user