KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > lexer > batch > BatchTokenList


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.lib.lexer.batch;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Set JavaDoc;
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 /**
40  * Token list used for root list for immutable inputs.
41  *
42  * @author Miloslav Metelka
43  * @version 1.00
44  */

45
46 public abstract class BatchTokenList<T extends TokenId>
47 extends ArrayList JavaDoc<Object JavaDoc> implements TokenList<T> {
48     
49     /** Flag for additional correctness checks (may degrade performance). */
50     private static final boolean testing = Boolean.getBoolean("netbeans.debug.lexer.test");
51     
52     private static boolean maintainLAState;
53     
54     /**
55      * Check whether lookaheads and states are stored for testing purposes.
56      */

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 JavaDoc<T> skipTokenIds;
70     
71     private final InputAttributes inputAttributes;
72     
73     /**
74      * Lexer input used for lexing of the input.
75      */

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 JavaDoc<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) { // Maintain lookaheads and states when in test environment
90
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; // this list should always be the root list of the token hierarchy
104
}
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) { // still lexing
120
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         // Children offsets should be absolute
131
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 { // non-flyweight offset
148
offset = token.offset(null);
149         }
150         return offset;
151     }
152
153     public synchronized Object JavaDoc tokenOrEmbeddingContainer(int index) {
154         return tokenOrEmbeddingContainerImpl(index);
155     }
156     
157     private Object JavaDoc 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) { // lexer returned valid token
165
add(token);
166                 if (laState != null) { // maintaining lookaheads and states
167
laState = laState.add(lexerInputOperation.lookahead(),
168                             lexerInputOperation.lexerState());
169                 }
170             } else { // no more tokens from lexer
171
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 JavaDoc state(int index) {
188         return (laState != null) ? laState.state(index) : null;
189     }
190
191     public int modCount() {
192         return -1; // immutable input
193
}
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 JavaDoc<T> skipTokenIds() {
215         return skipTokenIds;
216     }
217
218 }
219
Popular Tags