1 19 20 package org.netbeans.lib.lexer; 21 22 import java.util.Collection ; 23 import java.util.Iterator ; 24 import java.util.AbstractSet ; 25 import java.util.NoSuchElementException ; 26 import java.util.Set ; 27 import org.netbeans.api.lexer.Language; 28 import org.netbeans.api.lexer.TokenId; 29 30 39 40 public final class TokenIdSet<T extends TokenId> extends AbstractSet <T> { 41 42 45 public static int findMaxOrdinal(Collection <? extends TokenId> ids) { 46 int maxOrdinal = -1; 47 for (TokenId id : ids) { 48 maxOrdinal = Math.max(maxOrdinal, id.ordinal()); 49 } 50 return maxOrdinal; 51 } 52 53 public static <T extends TokenId> void checkIdsFromLanguage(Collection <T> ids, Set <T> languageIds) { 54 for (T id : ids) { 55 if (id != null && !languageIds.contains(id)) { 56 throw new IllegalArgumentException (id + "not contained in " + languageIds); } 58 } 59 } 60 61 62 final T[] indexedIds; 63 64 private int size = -1; 65 66 75 public TokenIdSet(Collection <T> ids, int maxOrdinal, boolean checkDupOrdinals) { 76 indexedIds = allocateIds(maxOrdinal + 1); 77 if (ids != null) { 78 for (T id : ids) { 79 if (id != null) { 80 if (checkDupOrdinals && indexedIds[id.ordinal()] != null) { 81 throw new IllegalStateException (id + " has duplicate ordinal with " + indexedIds[id.ordinal()]); } 84 indexedIds[id.ordinal()] = id; 85 } 86 } 87 } 88 } 89 90 @SuppressWarnings ("unchecked") private T[] allocateIds(int size) { 91 return (T[])new TokenId[size]; 92 } 93 94 public boolean add(T id) { 95 T origId = indexedIds[id.ordinal()]; 96 indexedIds[id.ordinal()] = id; 97 size = -1; 98 return (origId != null); 99 } 100 101 public boolean remove(T id) { 102 T origId = indexedIds[id.ordinal()]; 103 indexedIds[id.ordinal()] = null; 104 size = -1; 105 return (origId != null); 106 } 107 108 public T[] indexedIds() { 109 return indexedIds; 110 } 111 112 public int size() { 113 int cnt = size; 114 if (cnt < 0) { 115 cnt = 0; 118 for (Iterator it = iterator(); it.hasNext();) { 119 it.next(); 120 cnt++; 121 } 122 size = cnt; 123 } 124 125 return cnt; 126 } 127 128 public Iterator <T> iterator() { 129 return new SkipNullsIterator(); 130 } 131 132 public boolean containsTokenId(TokenId id) { 133 int ordinal = id.ordinal(); 134 return (ordinal >= 0 && ordinal < indexedIds.length && indexedIds[ordinal] == id); 135 } 136 137 public boolean contains(Object o) { 138 return (o instanceof TokenId) 139 ? containsTokenId((TokenId)o) 140 : false; 141 } 142 143 public String toString() { 144 StringBuilder sb = new StringBuilder ("{\n"); 145 for (Iterator it = iterator(); it.hasNext();) { 146 TokenId id = (TokenId) it.next(); 147 sb.append(" "); 148 sb.append(LexerUtilsConstants.idToString(id)); 149 sb.append('\n'); 150 } 151 sb.append("}\n"); 152 return sb.toString(); 153 } 154 155 156 private final class SkipNullsIterator implements Iterator <T> { 157 158 private int index; 159 160 private int lastRetIndex = -1; 161 162 SkipNullsIterator() { 163 } 164 165 public boolean hasNext() { 166 while (index < indexedIds.length) { 167 if (indexedIds[index] != null) { 168 return true; 169 } 170 index++; 171 } 172 return false; 173 } 174 175 public T next() { 176 while (index < indexedIds.length) { 177 T tokenId = indexedIds[index++]; 178 if (tokenId != null) { 179 lastRetIndex = index - 1; 180 return tokenId; 181 } 182 } 183 184 throw new NoSuchElementException (); 185 } 186 187 public void remove() { 188 if (lastRetIndex >= 0) { 189 indexedIds[lastRetIndex] = null; 190 size = -1; 191 } else { 192 throw new IllegalStateException (); } 194 } 195 196 } 197 198 } 199 200 | Popular Tags |