Merge remote branch 'origin/master'

This commit is contained in:
Andrey Breslav
2011-11-14 17:34:38 +03:00
18 changed files with 202 additions and 86 deletions
@@ -1,6 +1,7 @@
package org.jetbrains.jet.lang.resolve;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
@@ -12,7 +13,7 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.DeferredType;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.util.CommonSuppliers;
import org.jetbrains.jet.util.Box;
import org.jetbrains.jet.util.slicedmap.*;
import java.util.Collection;
@@ -51,10 +52,10 @@ public interface BindingContext {
WritableSlice<VariableDescriptor, Boolean> MUST_BE_WRAPPED_IN_A_REF = Slices.createSimpleSetSlice();
enum DeferredTypeKey {DEFERRED_TYPE_KEY}
WritableSlice<DeferredTypeKey, Collection<DeferredType>> DEFERRED_TYPES = Slices.createSimpleSlice();
WritableSlice<DeferredTypeKey, DeferredType> DEFERRED_TYPE = new CollectionSliceWrapper<DeferredTypeKey, DeferredType>(DEFERRED_TYPES, CommonSuppliers.<DeferredType>getArrayListSupplier());
// enum DeferredTypeKey {DEFERRED_TYPE_KEY}
// WritableSlice<DeferredTypeKey, Collection<DeferredType>> DEFERRED_TYPES = Slices.createSimpleSlice();
WritableSlice<Box<DeferredType>, Boolean> DEFERRED_TYPE = Slices.createCollectiveSetSlice();
WritableSlice<PropertyDescriptor, Boolean> BACKING_FIELD_REQUIRED = new Slices.SetSlice<PropertyDescriptor>(RewritePolicy.DO_NOTHING) {
@Override
@@ -139,4 +140,8 @@ public interface BindingContext {
@Nullable
<K, V> V get(ReadOnlySlice<K, V> slice, K key);
// slice.isCollective() must be true
@NotNull
<K, V> Collection<K> getKeys(WritableSlice<K, V> slice);
}
@@ -1,10 +1,13 @@
package org.jetbrains.jet.lang.resolve;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import java.util.Collection;
/**
* @author abreslav
*/
@@ -19,4 +22,8 @@ public interface BindingTrace extends DiagnosticHolder {
@Nullable
<K, V> V get(ReadOnlySlice<K, V> slice, K key);
// slice.isCollective() must be true
@NotNull
<K, V> Collection<K> getKeys(WritableSlice<K, V> slice);
}
@@ -30,6 +30,12 @@ public class BindingTraceContext implements BindingTrace {
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
return BindingTraceContext.this.get(slice, key);
}
@NotNull
@Override
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
return BindingTraceContext.this.getKeys(slice);
}
};
@Override
@@ -56,4 +62,10 @@ public class BindingTraceContext implements BindingTrace {
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
return map.get(slice, key);
}
@NotNull
@Override
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
return map.getKeys(slice);
}
}
@@ -18,6 +18,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.util.Box;
import org.jetbrains.jet.util.lazy.ReenteringLazyValueComputationException;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
@@ -25,8 +26,6 @@ import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.DEFERRED_TYPE;
import static org.jetbrains.jet.lang.resolve.BindingContext.DEFERRED_TYPES;
import static org.jetbrains.jet.lang.resolve.BindingContext.DeferredTypeKey.DEFERRED_TYPE_KEY;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
/**
@@ -544,17 +543,17 @@ public class BodyResolver {
}
private void computeDeferredTypes() {
Collection<DeferredType> deferredTypes = context.getTrace().get(DEFERRED_TYPES, DEFERRED_TYPE_KEY);
Collection<Box<DeferredType>> deferredTypes = context.getTrace().getKeys(DEFERRED_TYPE);
if (deferredTypes != null) {
final Queue<DeferredType> queue = new Queue<DeferredType>(deferredTypes.size());
context.getTrace().addHandler(DEFERRED_TYPE, new ObservableBindingTrace.RecordHandler<BindingContext.DeferredTypeKey, DeferredType>() {
context.getTrace().addHandler(DEFERRED_TYPE, new ObservableBindingTrace.RecordHandler<Box<DeferredType>, Boolean>() {
@Override
public void handleRecord(WritableSlice<BindingContext.DeferredTypeKey, DeferredType> deferredTypeKeyDeferredTypeWritableSlice, BindingContext.DeferredTypeKey key, DeferredType value) {
queue.addLast(value);
public void handleRecord(WritableSlice<Box<DeferredType>, Boolean> deferredTypeKeyDeferredTypeWritableSlice, Box<DeferredType> key, Boolean value) {
queue.addLast(key.getData());
}
});
for (DeferredType deferredType : deferredTypes) {
queue.addLast(deferredType);
for (Box<DeferredType> deferredType : deferredTypes) {
queue.addLast(deferredType.getData());
}
while (!queue.isEmpty()) {
DeferredType deferredType = queue.pullFirst();
@@ -27,6 +27,13 @@ public class DelegatingBindingTrace implements BindingTrace {
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
return DelegatingBindingTrace.this.get(slice, key);
}
@NotNull
@Override
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
return DelegatingBindingTrace.this.getKeys(slice);
}
};
public DelegatingBindingTrace(BindingContext parentContext) {
@@ -56,6 +63,19 @@ public class DelegatingBindingTrace implements BindingTrace {
return parentContext.get(slice, key);
}
@NotNull
@Override
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
Collection<K> keys = map.getKeys(slice);
Collection<K> fromParent = parentContext.getKeys(slice);
if (keys.isEmpty()) return fromParent;
if (fromParent.isEmpty()) return keys;
List<K> result = Lists.newArrayList(keys);
result.addAll(fromParent);
return result;
}
public void addAllMyDataTo(BindingTrace trace) {
for (Map.Entry<SlicedMapKey<?, ?>, ?> entry : map) {
SlicedMapKey slicedMapKey = entry.getKey();
@@ -6,6 +6,7 @@ import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import java.util.Collection;
import java.util.Map;
/**
@@ -16,13 +17,14 @@ public class ObservableBindingTrace implements BindingTrace {
void handleRecord(WritableSlice<K, V> slice, K key, V value);
}
private final BindingTrace originalTrace;
private Map<WritableSlice, RecordHandler> handlers = Maps.newHashMap();
public ObservableBindingTrace(BindingTrace originalTrace) {
this.originalTrace = originalTrace;
}
@Override
public void report(@NotNull Diagnostic diagnostic) {
originalTrace.report(diagnostic);
@@ -51,7 +53,13 @@ public class ObservableBindingTrace implements BindingTrace {
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
return originalTrace.get(slice, key);
}
@Override
@NotNull
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
return originalTrace.getKeys(slice);
}
public <K, V> ObservableBindingTrace addHandler(@NotNull WritableSlice<K, V> slice, @NotNull RecordHandler<K, V> handler) {
handlers.put(slice, handler);
return this;
@@ -4,13 +4,13 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.util.Box;
import org.jetbrains.jet.util.lazy.LazyValue;
import org.jetbrains.jet.util.lazy.ReenteringLazyValueComputationException;
import java.util.List;
import static org.jetbrains.jet.lang.resolve.BindingContext.DEFERRED_TYPE;
import static org.jetbrains.jet.lang.resolve.BindingContext.DeferredTypeKey.DEFERRED_TYPE_KEY;
/**
* @author abreslav
@@ -19,7 +19,7 @@ public class DeferredType implements JetType {
public static DeferredType create(BindingTrace trace, LazyValue<JetType> lazyValue) {
DeferredType deferredType = new DeferredType(lazyValue);
trace.record(DEFERRED_TYPE, DEFERRED_TYPE_KEY, deferredType);
trace.record(DEFERRED_TYPE, new Box<DeferredType>(deferredType));
return deferredType;
}
@@ -0,0 +1,26 @@
package org.jetbrains.jet.util;
/**
* @author abreslav
*/
public class Box<T> {
private final T data;
public Box(T data) {
this.data = data;
}
public T getData() {
return data;
}
@Override
public int hashCode() {
return super.hashCode(); // This class is needed to screen from calling data's hashCode()
}
@Override
public boolean equals(Object obj) {
return super.equals(obj); // This class is needed to screen from calling data's equals()
}
}
@@ -27,6 +27,13 @@ public class CommonSuppliers {
}
};
private static final Supplier<?> HASH_SET_SUPPLIER = new Supplier() {
@Override
public Set get() {
return Sets.newHashSet();
}
};
public static <T> Supplier<List<T>> getArrayListSupplier() {
//noinspection unchecked
return (Supplier<List<T>>) ARRAY_LIST_SUPPLIER;
@@ -36,7 +43,12 @@ public class CommonSuppliers {
//noinspection unchecked
return (Supplier<Set<T>>) LINKED_HASH_SET_SUPPLIER;
}
public static <T> Supplier<Set<T>> getHashSetSupplier() {
//noinspection unchecked
return (Supplier<Set<T>>) HASH_SET_SUPPLIER;
}
public static <K, V> SetMultimap<K, V> newLinkedHashSetHashSetMultimap() {
return Multimaps.newSetMultimap(Maps.<K, Collection<V>>newHashMap(), CommonSuppliers.<V>getLinkedHashSetSupplier());
}
@@ -39,8 +39,8 @@ public class BasicWritableSlice<K, V> implements WritableSlice<K,V> {
// True to put, false to skip
@Override
public boolean check(K key, V value) {
assert key != null;
assert value != null;
// assert key != null : this + " called with null key";
assert value != null : this + " called with null value";
return true;
}
@@ -60,6 +60,10 @@ public class BasicWritableSlice<K, V> implements WritableSlice<K,V> {
return rewritePolicy;
}
@Override
public boolean isCollective() {
return false;
}
@Override
public String toString() {
@@ -1,57 +0,0 @@
package org.jetbrains.jet.util.slicedmap;
import com.google.common.base.Supplier;
import java.util.Collection;
/**
* @author abreslav
*/
public class CollectionSliceWrapper<K, V> implements WritableSlice<K, V> {
private final WritableSlice<K, Collection<V>> wrapped;
private final SlicedMapKey<K, V> myKey;
private final Supplier<? extends Collection<V>> supplier;
public CollectionSliceWrapper(WritableSlice<K, Collection<V>> wrapped, Supplier<? extends Collection<V>> supplier) {
this.wrapped = wrapped;
this.supplier = supplier;
this.myKey = new SlicedMapKey<K, V>(this, null);
}
@Override
public SlicedMapKey<K, V> makeKey(K key) {
return myKey;
}
@Override
public boolean check(K key, V value) {
assert value != null;
return true;
}
@Override
public void afterPut(MutableSlicedMap map, K key, V value) {
Collection<V> collection = map.get(wrapped, key);
if (collection == null) {
collection = supplier.get();
map.put(wrapped, key, collection);
}
collection.add(value);
}
@Override
public RewritePolicy getRewritePolicy() {
return RewritePolicy.DO_NOTHING;
}
@Override
public V computeValue(SlicedMap map, K key, V value, boolean valueNotFound) {
throw new UnsupportedOperationException("Don't read by this slice, use the wrapped one");
}
@Override
public ReadOnlySlice<K, V> makeRawValueVersion() {
return this;
}
}
@@ -12,6 +12,11 @@ public class DelegatingSlice<K, V> implements WritableSlice<K, V> {
this.delegate = delegate;
}
@Override
public boolean isCollective() {
return delegate.isCollective();
}
public boolean check(K key, V value) {
return delegate.check(key, value);
}
@@ -1,5 +1,6 @@
package org.jetbrains.jet.util.slicedmap;
import java.util.Collection;
import java.util.Map;
/**
@@ -9,6 +10,7 @@ public interface SlicedMap extends Iterable<Map.Entry<SlicedMapKey<?, ?>, ?>> {
<K, V> V get(ReadOnlySlice<K, V> slice, K key);
<K, V> boolean containsKey(ReadOnlySlice<K, V> slice, K key);
// slice.isCollective() must return true
<K, V> Collection<K> getKeys(WritableSlice<K, V> slice);
}
@@ -1,7 +1,12 @@
package org.jetbrains.jet.util.slicedmap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import org.jetbrains.jet.util.CommonSuppliers;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -23,6 +28,7 @@ public class SlicedMapImpl implements MutableSlicedMap {
}
private final Map<SlicedMapKey<?, ?>, Object> map;
private final Multimap<WritableSlice<?, ?>, Object> collectiveSliceKeys = Multimaps.newListMultimap(new HashMap<WritableSlice<?, ?>, Collection<Object>>(), CommonSuppliers.getArrayListSupplier());
private SlicedMapImpl(Map<SlicedMapKey<?, ?>, Object> map) {
this.map = map;
@@ -33,6 +39,7 @@ public class SlicedMapImpl implements MutableSlicedMap {
if (!slice.check(key, value)) {
return;
}
SlicedMapKey<K, V> slicedMapKey = slice.makeKey(key);
RewritePolicy rewritePolicy = slice.getRewritePolicy();
if (rewritePolicy.rewriteProcessingNeeded(key)) {
@@ -43,6 +50,11 @@ public class SlicedMapImpl implements MutableSlicedMap {
}
}
}
if (slice.isCollective()) {
collectiveSliceKeys.put(slice, key);
}
map.put(slicedMapKey, value);
slice.afterPut(this, key, value);
}
@@ -60,6 +72,13 @@ public class SlicedMapImpl implements MutableSlicedMap {
return slice.computeValue(this, key, value, value == null && !map.containsKey(slicedMapKey));
}
@Override
@SuppressWarnings("unchecked")
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
assert slice.isCollective() : "Keys are not collected for slice " + slice;
return (Collection<K>) collectiveSliceKeys.get(slice);
}
@Override
public <K, V> boolean containsKey(ReadOnlySlice<K, V> slice, K key) {
return map.containsKey(slice.makeKey(key));
@@ -17,7 +17,10 @@ public class Slices {
@Override
public <K, V> boolean processRewrite(WritableSlice<K, V> slice, K key, V oldValue, V newValue) {
assert (oldValue == null && newValue == null) || (oldValue != null && oldValue.equals(newValue))
: "Rewrite at slice " + slice + " key: " + key + " old value: " + oldValue + " new value: " + newValue;
: "Rewrite at slice " + slice +
" key: " + key +
" old value: " + oldValue + '@' + System.identityHashCode(oldValue) +
" new value: " + newValue + '@' + System.identityHashCode(newValue);
return true;
}
};
@@ -45,8 +48,13 @@ public class Slices {
public static <K> WritableSlice<K, Boolean> createSimpleSetSlice() {
return createRemovableSetSlice();
}
public static <K> WritableSlice<K, Boolean> createCollectiveSetSlice() {
return new SetSlice<K>(RewritePolicy.DO_NOTHING, true);
}
public static <K> RemovableSlice<K, Boolean> createRemovableSetSlice() {
return new SetSlice<K>(RewritePolicy.DO_NOTHING);
return new SetSlice<K>(RewritePolicy.DO_NOTHING, false);
}
public static class SliceBuilder<K, V> {
@@ -157,8 +165,15 @@ public class Slices {
public static class SetSlice<K> extends BasicRemovableSlice<K, Boolean> {
private final boolean collective;
protected SetSlice(RewritePolicy rewritePolicy) {
this(rewritePolicy, false);
}
protected SetSlice(RewritePolicy rewritePolicy, boolean collective) {
super(rewritePolicy);
this.collective = collective;
}
@Override
@@ -167,6 +182,10 @@ public class Slices {
return super.computeValue(map, key, value, valueNotFound);
}
@Override
public boolean isCollective() {
return collective;
}
}
}
@@ -10,4 +10,7 @@ public interface WritableSlice<K, V> extends ReadOnlySlice<K, V> {
void afterPut(MutableSlicedMap map, K key, V value);
RewritePolicy getRewritePolicy();
// In a sliced map one can request all keys for a collective slice
boolean isCollective();
}
@@ -0,0 +1,5 @@
fun foo(a : Any) {}
fun test() {
foo(object {});
}
@@ -10,6 +10,7 @@ import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import java.util.Collection;
import java.util.Collections;
/**
* @author abreslav
@@ -31,6 +32,12 @@ public class JetTestUtils {
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
return DUMMY_TRACE.get(slice, key);
}
@NotNull
@Override
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
return DUMMY_TRACE.getKeys(slice);
}
};
}
@@ -48,6 +55,13 @@ public class JetTestUtils {
return null;
}
@NotNull
@Override
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
assert slice.isCollective();
return Collections.emptySet();
}
@Override
public void report(@NotNull Diagnostic diagnostic) {
if (diagnostic instanceof UnresolvedReferenceDiagnostic) {
@@ -70,6 +84,12 @@ public class JetTestUtils {
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
return DUMMY_EXCEPTION_ON_ERROR_TRACE.get(slice, key);
}
@NotNull
@Override
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
return DUMMY_EXCEPTION_ON_ERROR_TRACE.getKeys(slice);
}
};
}
@@ -86,11 +106,18 @@ public class JetTestUtils {
return null;
}
@NotNull
@Override
public void report(@NotNull Diagnostic diagnostic) {
if (diagnostic.getSeverity() == Severity.ERROR) {
throw new IllegalStateException(diagnostic.getMessage());
}
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
assert slice.isCollective();
return Collections.emptySet();
}
};
@Override
public void report(@NotNull Diagnostic diagnostic) {
if (diagnostic.getSeverity() == Severity.ERROR) {
throw new IllegalStateException(diagnostic.getMessage());
}
}
};
}