KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > lexer > PreprocessedTextLexerInputOperation


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;
21
22 import org.netbeans.api.lexer.TokenId;
23 import org.netbeans.spi.lexer.LexerInput;
24
25 /**
26  * Used when branching a token with preprocessed text.
27  *
28  * @author Miloslav Metelka
29  * @version 1.00
30  */

31
32 public final class PreprocessedTextLexerInputOperation<T extends TokenId> extends TextLexerInputOperation<T> {
33
34     private final PreprocessedTextStorage preprocessedText;
35
36     private int prepStartIndex;
37
38     private int prepEndIndex;
39
40     private int tokenStartRawLengthShift;
41     
42     private int lastRawLengthShift;
43     
44     private int tokenEndRawLengthShift;
45
46     public PreprocessedTextLexerInputOperation(TokenList<T> tokenList, PreprocessedTextStorage prepText) {
47         this(tokenList, 0, null, prepText, 0, 0, prepText.length());
48     }
49
50     public PreprocessedTextLexerInputOperation(TokenList<T> tokenList, int tokenIndex,
51     Object JavaDoc lexerRestartState, PreprocessedTextStorage prepText, int prepTextStartOffset,
52     int startOffset, int endOffset) {
53         super(tokenList, tokenIndex, lexerRestartState, prepText,
54                 prepTextStartOffset, startOffset, endOffset);
55         this.preprocessedText = prepText;
56         int index = startOffset - prepTextStartOffset;
57         if (index > 0) {
58             tokenStartRawLengthShift = preprocessedText.rawLengthShift(index);
59             lastRawLengthShift = tokenStartRawLengthShift;
60         }
61         preprocessingLevelCount++; // extra level of preprocessing
62
}
63
64     public int deepRawLength(int length) {
65         return length + preprocessedText.rawLengthShift(tokenStartIndex() + length - 1)
66                 - tokenStartRawLengthShift;
67     }
68     
69     public int deepRawLengthShift(int index) {
70         return preprocessedText.rawLengthShift(tokenStartIndex() + index)
71                 - tokenStartRawLengthShift;
72     }
73
74     public int read(int index) { // index >= 0 is guaranteed by contract
75
index += tokenStartIndex();
76         if (index < readEndIndex()) {
77             // Check whether the char is preprocessed
78
int rls = preprocessedText.rawLengthShift(index);
79             if (rls != lastRawLengthShift) { // Preprocessed
80
lastRawLengthShift = rls;
81                 if (prepStartIndex >= index) { // prepStartIndex already inited
82
prepStartIndex = index;
83                 }
84                 prepEndIndex = index + 1;
85             }
86             return preprocessedText.charAt(index);
87         } else { // must read next or return EOF
88
return LexerInput.EOF;
89         }
90     }
91
92     public void tokenRecognized(int tokenLength) {
93         super.tokenRecognized(tokenLength);
94         tokenEndRawLengthShift = preprocessedText.rawLengthShift(
95                 tokenStartIndex() + tokenLength() - 1);
96     }
97     
98     public void tokenApproved() {
99         // Increase base raw length shift by the token's last-char shift
100
tokenStartRawLengthShift += tokenEndRawLengthShift;
101
102         if (prepStartIndex != Integer.MAX_VALUE) { // some prep chars (may be after token length)
103
if (prepStartIndex < tokenLength()) { // prep chars before token end
104
if (prepEndIndex <= tokenLength()) { // no preprocessed chars past token end
105
prepStartIndex = Integer.MAX_VALUE; // signal no preprocessed chars
106
} else { // prepEndIndex > tokenLength => initial prep chars in the next token
107
prepStartIndex = 0;
108                     prepEndIndex -= tokenLength();
109                 }
110
111             } else { // prepStartIndex >= tokenLength
112
prepStartIndex -= tokenLength();
113                 prepEndIndex -= tokenLength();
114             }
115         }
116         super.tokenApproved();
117     }
118     
119     public void collectExtraPreprocessedChars(CharProvider.ExtraPreprocessedChars epc,
120     int prepStartIndex, int prepEndIndex, int topPrepEndIndex) {
121         if (prepStartIndex < tokenLength()) { // Some preprocessed characters
122
// Check for any pre-prepChars
123
int preCount = Math.max(prepStartIndex - this.prepStartIndex, 0);
124             // Check for post-prepChars
125
int postCount;
126             if (this.prepEndIndex > tokenLength()) {
127                 postCount = tokenLength() - prepEndIndex;
128                 if (postCount > 0) {
129                     int i = tokenLength() - 2;
130                     // Optimize the case when there are lookahead chars
131
// for the present token and the ending chars could possibly
132
// be non-preprocessed (prepEndIndex > tokenLength)
133
while (--i >= prepStartIndex && postCount > 0
134                             && preprocessedText.rawLengthShift(i + tokenStartIndex()) == tokenEndRawLengthShift
135                     ) { // not preprocessed
136
postCount--;
137                     }
138                 } else // postCount <= 0
139
postCount = 0;
140                 
141             } else { // this.prepEndIndex <= tokenLength
142
postCount = this.prepEndIndex - prepEndIndex;
143             }
144             
145             assert (preCount >= 0 && postCount >= 0);
146             epc.ensureExtraLength(preCount + postCount);
147             while (--preCount >= 0) {
148                 epc.insert(readExisting(prepStartIndex - 1), deepRawLength(prepStartIndex) - prepStartIndex);
149                 prepStartIndex--;
150             }
151             while (--postCount >= 0) {
152                 epc.append(readExisting(prepEndIndex), deepRawLength(prepEndIndex) - topPrepEndIndex);
153                 prepEndIndex++;
154                 topPrepEndIndex++;
155             }
156         }
157     }
158
159 }
160
Popular Tags