1 19 20 package org.netbeans.spi.lexer; 21 22 import java.util.Set ; 23 import org.netbeans.api.lexer.PartType; 24 import org.netbeans.api.lexer.Token; 25 import org.netbeans.api.lexer.TokenId; 26 import org.netbeans.lib.editor.util.CharSequenceUtilities; 27 import org.netbeans.lib.lexer.LanguageOperation; 28 import org.netbeans.lib.lexer.LexerInputOperation; 29 import org.netbeans.lib.lexer.TokenIdImpl; 30 import org.netbeans.lib.lexer.token.CustomTextToken; 31 import org.netbeans.lib.lexer.token.DefaultToken; 32 import org.netbeans.lib.lexer.token.ComplexToken; 33 import org.netbeans.lib.lexer.token.PreprocessedTextToken; 34 import org.netbeans.lib.lexer.token.ComplexToken; 35 import org.netbeans.lib.lexer.token.PropertyToken; 36 import org.netbeans.lib.lexer.token.TextToken; 37 38 46 47 public final class TokenFactory<T extends TokenId> { 48 49 50 private static final boolean testing = Boolean.getBoolean("netbeans.debug.lexer.test"); 51 52 57 public static final Token SKIP_TOKEN 58 = new TextToken<TokenId>( 59 new TokenIdImpl("skip-token-id(should never be part of token sequence", 0, null), "" ); 62 63 private final LexerInputOperation<T> operation; 64 65 TokenFactory(LexerInputOperation<T> operation) { 66 this.operation = operation; 67 } 68 69 75 public Token<T> createToken(T id) { 76 return createToken(id, operation.readIndex()); 77 } 78 79 94 public Token<T> createToken(T id, int length) { 95 if (isSkipToken(id)) { 96 operation.tokenRecognized(length, true); 97 return skipToken(); 98 } else { if (operation.tokenRecognized(length, false)) { return new PreprocessedTextToken<T>(id, operation.tokenLength()); 101 } else { 102 return new DefaultToken<T>(id, operation.tokenLength()); 103 } 104 } 105 } 106 107 123 public Token<T> createToken(T id, int length, PartType partType) { 124 checkPartTypeNonNull(partType); 125 if (partType == PartType.COMPLETE) 126 return createToken(id, length); 127 128 if (isSkipToken(id)) { 129 operation.tokenRecognized(length, true); 130 return skipToken(); 131 } else { if (operation.tokenRecognized(length, false)) { return new ComplexToken<T>(id, operation.tokenLength(), null, null, partType); 134 } else { 135 return new PropertyToken<T>(id, operation.tokenLength(), null, partType); 136 } 137 } 138 } 139 140 161 public Token<T> getFlyweightToken(T id, String text) { 162 assert (text.length() <= operation.readIndex()); 163 if (testing) { 165 for (int i = 0; i < text.length(); i++) { 166 if (text.charAt(i) != operation.readExisting(i)) { 167 throw new IllegalArgumentException ("Flyweight text in " + "TokenFactory.getFlyweightToken(" + id + ", \"" + CharSequenceUtilities.debugText(text) + "\") " + "differs from recognized text: '" + CharSequenceUtilities.debugChar(operation.readExisting(i)) + 172 "' != '" + CharSequenceUtilities.debugChar(text.charAt(i)) + "' at index=" + i ); 175 } 176 } 177 } 178 179 if (isSkipToken(id)) { 181 operation.tokenRecognized(text.length(), true); 182 return skipToken(); 183 } else { if (operation.tokenRecognized(text.length(), false)) { return new PreprocessedTextToken<T>(id, operation.tokenLength()); 186 } else if (operation.isFlyTokenAllowed()) { 187 LanguageOperation<T> langOp = operation.languageOperation(); 188 return langOp.getFlyweightToken(id, text); 189 } else { return new DefaultToken<T>(id, operation.tokenLength()); 191 } 192 } 193 } 194 195 213 public Token<T> createPropertyToken(T id, int length, 214 TokenPropertyProvider propertyProvider, PartType partType) { 215 checkPartTypeNonNull(partType); 216 if (isSkipToken(id)) { 217 operation.tokenRecognized(length, true); 218 return skipToken(); 219 } else { if (operation.tokenRecognized(length, false)) { return new ComplexToken<T>(id, operation.tokenLength(), 222 propertyProvider, null, partType); 223 } else { 224 return new PropertyToken<T>(id, operation.tokenLength(), 225 propertyProvider, partType); 226 } 227 } 228 } 229 230 234 public Token<T> createCustomTextToken(T id, CharSequence text, int length, PartType partType) { 235 checkPartTypeNonNull(partType); 236 if (isSkipToken(id)) { 237 operation.tokenRecognized(length, true); 238 return skipToken(); 239 } else { if (operation.tokenRecognized(length, false)) { return new ComplexToken<T>(id, operation.tokenLength(), null, text, partType); 242 } else { 243 return new CustomTextToken<T>(id, operation.tokenLength(), text, partType); 244 } 245 } 246 } 247 248 private boolean isSkipToken(T id) { 249 Set <? extends TokenId> skipTokenIds = operation.skipTokenIds(); 250 return (skipTokenIds != null) && skipTokenIds.contains(id); 251 } 252 253 @SuppressWarnings ("unchecked") private Token<T> skipToken() { 255 return SKIP_TOKEN; 256 } 257 258 private void checkPartTypeNonNull(PartType partType) { 259 if (partType == null) 260 throw new IllegalArgumentException ("partType must be non-null"); 261 } 262 263 } 264 | Popular Tags |