Merge remote branch 'origin/master'

This commit is contained in:
irengrig
2013-01-30 15:58:12 +04:00
10 changed files with 82 additions and 43 deletions
@@ -221,7 +221,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
if (nullPassed && currentSubstitution == null) return RAW_INFERENCE;
} else if (argumentType instanceof PsiMethodReferenceType) {
final PsiMethodReferenceExpression referenceExpression = ((PsiMethodReferenceType)argumentType).getExpression();
currentSubstitution = inferConstraintFromFunctionalInterfaceMethod(typeParameter, referenceExpression, partialSubstitutor.substitute(parameterType));
currentSubstitution = inferConstraintFromFunctionalInterfaceMethod(typeParameter, referenceExpression, partialSubstitutor.substitute(parameterType), partialSubstitutor, policy);
}
else {
currentSubstitution = getSubstitutionForTypeParameterConstraint(typeParameter, parameterType,
@@ -608,7 +608,9 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
@Nullable
private static Pair<PsiType, ConstraintType> inferConstraintFromFunctionalInterfaceMethod(final PsiTypeParameter typeParam,
final PsiMethodReferenceExpression methodReferenceExpression,
final PsiType functionalInterfaceType) {
final PsiType functionalInterfaceType,
final PsiSubstitutor partialSubstitutor,
final ParameterTypeInferencePolicy policy) {
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
final PsiMethod functionalInterfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
if (functionalInterfaceMethod != null) {
@@ -669,7 +671,14 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
} else {
argType = methReferenceResolveResult.getSubstitutor().substitute(subst.substitute(method.getReturnType()));
}
return getSubstitutionForTypeParameterConstraint(typeParam, functionalInterfaceReturnType, argType, true, PsiUtil.getLanguageLevel(functionalInterfaceMethod));
final Pair<PsiType, ConstraintType> typeParameterConstraint =
getSubstitutionForTypeParameterConstraint(typeParam, functionalInterfaceReturnType, argType, true, PsiUtil.getLanguageLevel(functionalInterfaceMethod));
if (typeParameterConstraint != null && typeParameterConstraint.getSecond() != ConstraintType.EQUALS && method.isConstructor()) {
final Pair<PsiType, ConstraintType> constraintFromParent =
inferMethodTypeParameterFromParent(typeParam, partialSubstitutor, methodReferenceExpression.getParent().getParent(), policy);
if (constraintFromParent != null && constraintFromParent.getSecond() == ConstraintType.EQUALS) return constraintFromParent;
}
return typeParameterConstraint;
}
}
}
@@ -0,0 +1,23 @@
import java.util.ArrayList;
import java.util.List;
public class IDEA99970 {
public static <T, C> Collector<T, C> toCollection(Supplier<C> collectionFactory) {
return null;
}
public static <T> Collector<T, List<T>> toList() {
return toCollection(ArrayList<T>::new);
}
public static <T> Collector<T, List<T>> toList1() {
return toCollection(ArrayList<T>::new);
}
}
interface Supplier<T> {
public T get();
}
interface Collector<T, R> {}
@@ -167,6 +167,10 @@ public class MethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testConstructorNonAbstractAbstractExpected() throws Exception {
doTest();
}
private void doTest() throws Exception {
doTest(false);
}
@@ -19,7 +19,7 @@
*/
package com.intellij.util.containers;
import com.intellij.util.containers.hash.HashingStrategy;
import com.intellij.util.containers.hash.EqualityPolicy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -28,7 +28,7 @@ public abstract class SLRUCache<K, V> extends SLRUMap<K,V> {
super(protectedQueueSize, probationalQueueSize);
}
protected SLRUCache(final int protectedQueueSize, final int probationalQueueSize, HashingStrategy<K> hashingStrategy) {
protected SLRUCache(final int protectedQueueSize, final int probationalQueueSize, EqualityPolicy<K> hashingStrategy) {
super(protectedQueueSize, probationalQueueSize, hashingStrategy);
}
@@ -20,7 +20,7 @@
package com.intellij.util.containers;
import com.intellij.util.Consumer;
import com.intellij.util.containers.hash.HashingStrategy;
import com.intellij.util.containers.hash.EqualityPolicy;
import com.intellij.util.containers.hash.LinkedHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,10 +41,10 @@ public class SLRUMap<K,V> {
private static final int FACTOR = Integer.getInteger("idea.slru.factor", 1);
public SLRUMap(final int protectedQueueSize, final int probationalQueueSize) {
this(protectedQueueSize, probationalQueueSize, (HashingStrategy<K>)HashingStrategy.CANONICAL);
this(protectedQueueSize, probationalQueueSize, (EqualityPolicy)EqualityPolicy.CANONICAL);
}
public SLRUMap(final int protectedQueueSize, final int probationalQueueSize, HashingStrategy<K> hashingStrategy) {
public SLRUMap(final int protectedQueueSize, final int probationalQueueSize, EqualityPolicy hashingStrategy) {
myProtectedQueueSize = protectedQueueSize * FACTOR;
myProbationalQueueSize = probationalQueueSize * FACTOR;
@@ -15,34 +15,35 @@
*/
package com.intellij.util.containers.hash;
public interface HashingStrategy<T> {
HashingStrategy<?> IDENTITY = new HashingStrategy() {
public interface EqualityPolicy<T> {
EqualityPolicy<?> IDENTITY = new EqualityPolicy() {
@Override
public int computeHashCode(Object object) {
return System.identityHashCode(object);
public int getHashCode(Object value) {
return System.identityHashCode(value);
}
@Override
public boolean equals(Object o1, Object o2) {
return o1 == o2;
public boolean isEqual(Object val1, Object val2) {
return val1 == val2;
}
};
HashingStrategy<?> CANONICAL = new HashingStrategy() {
EqualityPolicy<?> CANONICAL = new EqualityPolicy() {
@Override
public int computeHashCode(Object object) {
return object != null ? object.hashCode() : 0;
public int getHashCode(Object value) {
return value != null ? value.hashCode() : 0;
}
@Override
public boolean equals(Object o1, Object o2) {
return o1 != null ? o1.equals(o2) : o2 == null;
public boolean isEqual(Object val1, Object val2) {
return val1 != null ? val1.equals(val2) : val2 == null;
}
};
int getHashCode(T value);
int computeHashCode(T object);
boolean equals(T o1, T o2);
boolean isEqual(T val1, T val2);
}
@@ -35,9 +35,9 @@ class HashUtil {
}
public static int hash(Object key, HashingStrategy hashingStrategy) {
public static int hash(Object key, EqualityPolicy hashingStrategy) {
return key == null ? 0 : hashingStrategy.computeHashCode(key) & 0x7fffffff;
return key == null ? 0 : hashingStrategy.getHashCode(key) & 0x7fffffff;
}
@@ -28,7 +28,7 @@ public class LinkedHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>
private int capacity;
private int size;
private final float loadFactor;
private final HashingStrategy<K> hashingStrategy;
private final EqualityPolicy<K> hashingStrategy;
public LinkedHashMap() {
@@ -40,14 +40,14 @@ public class LinkedHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>
}
public LinkedHashMap(int capacity, float loadFactor) {
this(capacity, loadFactor, (HashingStrategy<K>)HashingStrategy.CANONICAL);
this(capacity, loadFactor, (EqualityPolicy)EqualityPolicy.CANONICAL);
}
public LinkedHashMap(HashingStrategy<K> hashingStrategy) {
public LinkedHashMap(EqualityPolicy hashingStrategy) {
this(0, HashUtil.DEFAULT_LOAD_FACTOR, hashingStrategy);
}
public LinkedHashMap(int capacity, float loadFactor, HashingStrategy<K> hashingStrategy) {
public LinkedHashMap(int capacity, float loadFactor, EqualityPolicy<K> hashingStrategy) {
this.loadFactor = loadFactor;
this.hashingStrategy = hashingStrategy;
clear(capacity);
@@ -72,7 +72,7 @@ public class LinkedHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>
for (Entry<K, V> e = table[index]; e != null; e = e.hashNext) {
final K entryKey;
if (e.keyHash == hash && ((entryKey = e.key) == key || hashingStrategy.equals(entryKey, (K)key))) {
if (e.keyHash == hash && ((entryKey = e.key) == key || hashingStrategy.isEqual(entryKey, (K)key))) {
moveToTop(e);
return e.value;
@@ -87,7 +87,7 @@ public class LinkedHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>
final int index = hash % table.length;
for (Entry<K, V> e = table[index]; e != null; e = e.hashNext) {
final K entryKey;
if (e.keyHash == hash && ((entryKey = e.key) == key || hashingStrategy.equals(entryKey, key))) {
if (e.keyHash == hash && ((entryKey = e.key) == key || hashingStrategy.isEqual(entryKey, key))) {
moveToTop(e);
return e.setValue(value);
}
@@ -132,7 +132,7 @@ public class LinkedHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>
return null;
}
K entryKey;
if (e.keyHash == hash && ((entryKey = e.key) == key || hashingStrategy.equals(entryKey, (K)key))) {
if (e.keyHash == hash && ((entryKey = e.key) == key || hashingStrategy.isEqual(entryKey, (K)key))) {
table[index] = e.hashNext;
}
else {
@@ -142,7 +142,7 @@ public class LinkedHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>
if (e == null) {
return null;
}
if (e.keyHash == hash && ((entryKey = e.key) == key || hashingStrategy.equals(entryKey, (K)key))) {
if (e.keyHash == hash && ((entryKey = e.key) == key || hashingStrategy.isEqual(entryKey, (K)key))) {
last.hashNext = e.hashNext;
break;
}
@@ -271,8 +271,8 @@ public class LinkedHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>
private abstract class LinkedHashIterator<T> implements Iterator<T> {
private Entry<K, V> e = top;
private Entry<K, V> last;
private LinkedHashMap.Entry<K, V> e = top;
private LinkedHashMap.Entry<K, V> last;
public boolean hasNext() {
return e != null;
@@ -15,8 +15,10 @@
*/
package com.intellij.util.io;
public interface EqualityPolicy<T> {
int getHashCode(T value);
boolean isEqual(T val1, T val2);
@Deprecated
/**
* Use {@link com.intellij.util.containers.hash.EqualityPolicy} directly
*/
public interface EqualityPolicy<T> extends com.intellij.util.containers.hash.EqualityPolicy<T>{
}
@@ -23,7 +23,7 @@ import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import com.intellij.util.containers.LimitedPool;
import com.intellij.util.containers.SLRUCache;
import com.intellij.util.containers.hash.HashingStrategy;
import com.intellij.util.containers.hash.EqualityPolicy;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -180,15 +180,15 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
}
private SLRUCache<Key, BufferExposingByteArrayOutputStream> createAppendCache(final KeyDescriptor<Key> keyDescriptor) {
final HashingStrategy<Key> hashingStrategy = new HashingStrategy<Key>() {
final EqualityPolicy<Key> hashingStrategy = new EqualityPolicy<Key>() {
@Override
public int computeHashCode(Key object) {
public int getHashCode(Key object) {
return keyDescriptor.getHashCode(object);
}
@Override
public boolean equals(Key o1, Key o2) {
return keyDescriptor.isEqual(o1, o2);
public boolean isEqual(Key val1, Key val2) {
return keyDescriptor.isEqual(val1, val2);
}
};
return new SLRUCache<Key, BufferExposingByteArrayOutputStream>(16 * 1024, 4 * 1024, hashingStrategy) {