1 19 20 package org.netbeans.lib.lexer.token; 21 22 import org.netbeans.api.lexer.PartType; 23 import org.netbeans.api.lexer.Token; 24 import org.netbeans.api.lexer.TokenHierarchy; 25 import org.netbeans.api.lexer.TokenId; 26 import org.netbeans.lib.editor.util.CharSequenceUtilities; 27 import org.netbeans.lib.lexer.EmbeddedTokenList; 28 import org.netbeans.lib.lexer.LexerApiPackageAccessor; 29 import org.netbeans.lib.lexer.TokenList; 30 31 37 38 public abstract class AbstractToken<T extends TokenId> extends Token<T> implements CharSequence { 39 40 private final T id; 42 private TokenList<T> tokenList; 44 private int rawOffset; 46 49 public AbstractToken(T id) { 50 assert (id != null); 51 this.id = id; 52 } 53 54 AbstractToken(T id, TokenList<T> tokenList, int rawOffset) { 55 this.id = id; 56 this.tokenList = tokenList; 57 this.rawOffset = rawOffset; 58 } 59 60 public abstract int length(); 61 62 67 @Override 68 public final T id() { 69 return id; 70 } 71 72 75 @Override 76 public CharSequence text() { 77 if (tokenList != null) { 78 if (tokenList.getClass() == EmbeddedTokenList.class) { 79 ((EmbeddedTokenList)tokenList).updateStartOffset(); 80 } 81 return this; 82 } else { 83 return null; 84 } 85 } 86 87 90 public final TokenList<T> tokenList() { 91 return tokenList; 92 } 93 94 97 public final void setTokenList(TokenList<T> tokenList) { 98 this.tokenList = tokenList; 99 } 100 101 106 public final int rawOffset() { 107 return rawOffset; 108 } 109 110 115 public final void setRawOffset(int rawOffset) { 116 this.rawOffset = rawOffset; 117 } 118 119 @Override 120 public final boolean isFlyweight() { 121 return (rawOffset == -1); 122 } 123 124 public final void makeFlyweight() { 125 setRawOffset(-1); 126 } 127 128 @Override 129 public PartType partType() { 130 return PartType.COMPLETE; 131 } 132 133 @Override 134 public boolean isCustomText() { 135 return false; 136 } 137 138 @Override 139 public final int offset(TokenHierarchy<?> tokenHierarchy) { 140 if (rawOffset == -1) { return -1; 142 } 143 144 if (tokenHierarchy != null) { 145 return LexerApiPackageAccessor.get().tokenHierarchyOperation( 146 tokenHierarchy).tokenOffset(this, tokenList, rawOffset); 147 } else { 148 return (tokenList != null) 149 ? tokenList.childTokenOffset(rawOffset) 150 : rawOffset; 151 } 152 } 153 154 @Override 155 public boolean isPreprocessedText() { 156 return false; 157 } 158 159 @Override 160 public CharSequence preprocessedText() { 161 return null; 162 } 163 164 @Override 165 public String preprocessError() { 166 return null; 167 } 168 169 @Override 170 public int preprocessErrorIndex() { 171 return -1; 172 } 173 174 @Override 175 public boolean hasProperties() { 176 return false; 177 } 178 179 @Override 180 public Object getProperty(Object key) { 181 return null; 182 } 183 184 188 public final char charAt(int index) { 189 if (index < 0 || index >= length()) { 190 throw new IndexOutOfBoundsException ( 191 "index=" + index + ", length=" + length() ); 193 } 194 195 return tokenList.childTokenCharAt(rawOffset, index); 196 } 197 198 public final CharSequence subSequence(int start, int end) { 199 return CharSequenceUtilities.toString(this, start, end); 200 } 201 202 205 public String toString() { 206 return CharSequenceUtilities.toString(this, 0, length()); 207 } 208 209 222 public String dumpInfo(TokenHierarchy tokenHierarchy) { 223 StringBuilder sb = new StringBuilder (); 224 sb.append(dumpInfoTokenType()); 225 sb.append('(').append(id()).append(", "); CharSequence text = text(); 227 if (text != null) { 228 sb.append('"'); 229 for (int i = 0; i < text.length(); i++) { 230 try { 231 CharSequenceUtilities.debugChar(sb, text.charAt(i)); 232 } catch (IndexOutOfBoundsException e) { 233 sb.append("IOOBE at index=").append(i).append("!!!"); break; 236 } 237 } 238 sb.append('"'); 239 } else { 240 sb.append("<null>"); } 242 sb.append(", ").append(offset(tokenHierarchy)).append(')'); return sb.toString(); 244 } 245 246 protected String dumpInfoTokenType() { 247 return "AbsT"; } 249 250 } 251 | Popular Tags |