1 19 20 package org.netbeans.lib.lexer.batch; 21 22 import java.util.ArrayList ; 23 import java.util.Set ; 24 import org.netbeans.api.lexer.Language; 25 import org.netbeans.api.lexer.LanguagePath; 26 import org.netbeans.lib.lexer.EmbeddingContainer; 27 import org.netbeans.lib.lexer.LAState; 28 import org.netbeans.lib.lexer.TokenList; 29 import org.netbeans.lib.lexer.LexerInputOperation; 30 import org.netbeans.lib.lexer.LexerUtilsConstants; 31 import org.netbeans.api.lexer.InputAttributes; 32 import org.netbeans.api.lexer.Token; 33 import org.netbeans.api.lexer.TokenId; 34 import org.netbeans.lib.lexer.TokenHierarchyOperation; 35 import org.netbeans.lib.lexer.token.AbstractToken; 36 import org.netbeans.lib.lexer.token.TextToken; 37 38 39 45 46 public abstract class BatchTokenList<T extends TokenId> 47 extends ArrayList <Object > implements TokenList<T> { 48 49 50 private static final boolean testing = Boolean.getBoolean("netbeans.debug.lexer.test"); 51 52 private static boolean maintainLAState; 53 54 57 public static boolean isMaintainLAState() { 58 return maintainLAState; 59 } 60 61 public static void setMaintainLAState(boolean maintainLAState) { 62 BatchTokenList.maintainLAState = maintainLAState; 63 } 64 65 private final TokenHierarchyOperation<?,T> tokenHierarchyOperation; 66 67 private final LanguagePath languagePath; 68 69 private final Set <T> skipTokenIds; 70 71 private final InputAttributes inputAttributes; 72 73 76 private LexerInputOperation<T> lexerInputOperation; 77 78 private LAState laState; 79 80 private boolean inited; 81 82 83 public BatchTokenList(TokenHierarchyOperation<?,T> tokenHierarchyOperation, 84 Language<T> language, Set <T> skipTokenIds, InputAttributes inputAttributes) { 85 this.tokenHierarchyOperation = tokenHierarchyOperation; 86 this.languagePath = LanguagePath.get(language); 87 this.skipTokenIds = skipTokenIds; 88 this.inputAttributes = inputAttributes; 89 if (testing) { laState = LAState.empty(); 91 } 92 } 93 94 public abstract char childTokenCharAt(int rawOffset, int index); 95 96 protected abstract LexerInputOperation<T> createLexerInputOperation(); 97 98 protected void init() { 99 lexerInputOperation = createLexerInputOperation(); 100 } 101 102 public TokenList<? extends TokenId> root() { 103 return this; } 105 106 public TokenHierarchyOperation<?,? extends TokenId> tokenHierarchyOperation() { 107 return tokenHierarchyOperation; 108 } 109 110 public LanguagePath languagePath() { 111 return languagePath; 112 } 113 114 public synchronized int tokenCount() { 115 if (!inited) { 116 init(); 117 inited = true; 118 } 119 if (lexerInputOperation != null) { tokenOrEmbeddingContainerImpl(Integer.MAX_VALUE); 121 } 122 return size(); 123 } 124 125 public int tokenCountCurrent() { 126 return size(); 127 } 128 129 public int childTokenOffset(int rawOffset) { 130 return rawOffset; 132 } 133 134 public int tokenOffset(int index) { 135 Token<T> token = existingToken(index); 136 int offset; 137 if (token.isFlyweight()) { 138 offset = 0; 139 while (--index >= 0) { 140 token = existingToken(index); 141 offset += token.length(); 142 if (!token.isFlyweight()) { 143 offset += token.offset(null); 144 break; 145 } 146 } 147 } else { offset = token.offset(null); 149 } 150 return offset; 151 } 152 153 public synchronized Object tokenOrEmbeddingContainer(int index) { 154 return tokenOrEmbeddingContainerImpl(index); 155 } 156 157 private Object tokenOrEmbeddingContainerImpl(int index) { 158 if (!inited) { 159 init(); 160 inited = true; 161 } 162 while (lexerInputOperation != null && index >= size()) { 163 Token<T> token = lexerInputOperation.nextToken(); 164 if (token != null) { add(token); 166 if (laState != null) { laState = laState.add(lexerInputOperation.lookahead(), 168 lexerInputOperation.lexerState()); 169 } 170 } else { lexerInputOperation.release(); 172 lexerInputOperation = null; 173 trimToSize(); 174 } 175 } 176 return (index < size()) ? get(index) : null; 177 } 178 179 private Token<T> existingToken(int index) { 180 return LexerUtilsConstants.token(get(index)); 181 } 182 183 public int lookahead(int index) { 184 return (laState != null) ? laState.lookahead(index) : -1; 185 } 186 187 public Object state(int index) { 188 return (laState != null) ? laState.state(index) : null; 189 } 190 191 public int modCount() { 192 return -1; } 194 195 public synchronized AbstractToken<T> replaceFlyToken( 196 int index, AbstractToken<T> flyToken, int offset) { 197 TextToken<T> nonFlyToken = ((TextToken<T>)flyToken).createCopy(this, offset); 198 set(index, nonFlyToken); 199 return nonFlyToken; 200 } 201 202 public void wrapToken(int index, EmbeddingContainer embeddingContainer) { 203 set(index, embeddingContainer); 204 } 205 206 public InputAttributes inputAttributes() { 207 return inputAttributes; 208 } 209 210 public boolean isContinuous() { 211 return (skipTokenIds == null); 212 } 213 214 public Set <T> skipTokenIds() { 215 return skipTokenIds; 216 } 217 218 } 219 | Popular Tags |