1 package com.intellij.codeInsight.dataflow;
3 import org.jetbrains.annotations.Nullable;
10 public class DFAMap<V> {
13 // if myAll != null, the map contains more than one value, and all of them are in myAll
14 // if myAll == null && myK != null, the map contains only one value (myK, myV)
15 // if myAll == null && myK == null, the map is empty
18 private HashMap<String, V> myAll;
20 private static final DFAMap ourEmptyMap = new DFAMap() {
22 public void put(String key, Object value) {
23 throw new UnsupportedOperationException();
27 public void remove(String name) {
28 throw new UnsupportedOperationException();
32 public DFAMap asWritable() {
40 private DFAMap(DFAMap<V> initialMap) {
43 myAll = initialMap.myAll == null ? null : new HashMap<String,V>(initialMap.myAll);
46 public static <V> DFAMap<V> empty() {
47 //noinspection unchecked
48 return (DFAMap<V>) ourEmptyMap;
51 public void addKeys(HashSet<String> allNames) {
53 allNames.addAll(myAll.keySet());
55 else if (myK != null) {
60 public void put(String key, V value) {
61 if ((myK == null || myK.equals(key)) && myAll == null) {
67 myAll = new HashMap<String,V>();
70 myAll.put(key, value);
75 public V get(String key) {
77 return myAll.get(key);
79 if (key.equals(myK)) {
85 public void remove(String name) {
88 if (myAll.size() == 1) {
89 final Map.Entry<String, V> e = myAll.entrySet().iterator().next();
95 else if (name.equals(myK)) {
101 public boolean containsKey(String name) {
103 return myAll.containsKey(name);
105 return name.equals(myK);
108 public Set<String> intersectKeys(@Nullable Set<String> names2Include) {
110 if (names2Include == null) return myAll.keySet();
111 return SetUtil.intersect(names2Include, myAll.keySet());
113 if (myK != null && (names2Include == null || names2Include.contains(myK))) {
114 if (names2Include != null && names2Include.size() == 1) return names2Include;
115 final HashSet<String> result = new HashSet<String>();
119 return Collections.emptySet();
123 public boolean equals(Object obj) {
124 if (!(obj instanceof DFAMap)) return false;
125 @SuppressWarnings({"unchecked"}) DFAMap<V> rhs = (DFAMap<V>) obj;
127 if (rhs.myAll != null) return false;
128 if (myK == null) return rhs.myK == null;
129 return myK.equals(rhs.myK) && myV.equals(rhs.myV);
132 if (rhs.myAll == null) return false;
133 return myAll.equals(rhs.myAll);
137 public Collection<V> values() {
139 return myAll.values();
142 return Collections.singletonList(myV);
144 return Collections.emptyList();
147 public Collection<? extends Map.Entry<String, V>> entrySet() {
149 return myAll.entrySet();
152 return Collections.singleton(new Map.Entry<String, V>() {
153 public String getKey() {
157 public V getValue() {
161 public V setValue(V value) {
162 throw new UnsupportedOperationException();
166 return Collections.emptyList();
169 public DFAMap<V> asWritable() {
170 return new DFAMap<V>(this);
174 public String toString() {
175 if (this == ourEmptyMap){
179 return myAll.toString();
182 return "{" + myK + "=" + myV + "}";
187 public Set<String> keySet() {
189 return myAll.keySet();
191 return myK != null ? Collections.singleton(myK) : Collections.<String>emptySet();