Files
openide/source/com/intellij/lexer/EscapedJavaLexer.java
Maxim Shafirov 7460e5adae initial
2005-01-13 23:44:30 +03:00

157 lines
3.8 KiB
Java

package com.intellij.lexer;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.tree.IElementType;
/**
* Used to process scriptlet code in JSP attribute values like this:
* attribute="<%=texts.get(\"Blabla\")%>"
*/
public class EscapedJavaLexer implements Lexer, Cloneable{
private char mySurroundingQuote;
private JavaLexer myJavaLexer;
private char[] myBuffer;
private int myBufferEnd;
private int myCurOffset;
private IElementType myTokenType = null;
private int myTokenEnd;
private static final int END_STATE = 10;
public EscapedJavaLexer(char surroundingQuote, LanguageLevel languageLevel) {
mySurroundingQuote = surroundingQuote;
myJavaLexer = new JavaLexer(languageLevel);
}
public char getSurroundingQuote() {
return mySurroundingQuote;
}
public void setSurroundingQuote(char surroundingQuote) {
mySurroundingQuote = surroundingQuote;
}
public Object clone() {
try{
EscapedJavaLexer clone = (EscapedJavaLexer)super.clone();
clone.myJavaLexer = (JavaLexer)clone.myJavaLexer.clone();
return clone;
}
catch(CloneNotSupportedException e){
return null;
}
}
public void start(char[] buffer) {
start(buffer, 0, buffer.length);
}
public void start(char[] buffer, int startOffset, int endOffset) {
myBuffer = buffer;
myCurOffset = startOffset;
myTokenEnd = startOffset;
myBufferEnd = endOffset;
myTokenType = null;
}
public void start(char[] buffer, int startOffset, int endOffset, int initialState) {
start(buffer, 0, buffer.length);
}
public int getState() {
return 0;
}
public int getLastState() {
return 0;
}
public IElementType getTokenType() {
locateToken();
return myTokenType;
}
public final int getTokenStart(){
locateToken();
return myCurOffset;
}
public final int getTokenEnd(){
locateToken();
return myTokenEnd;
}
public final void advance(){
locateToken();
myTokenType = null;
myCurOffset = myTokenEnd;
}
public final char[] getBuffer(){
return myBuffer;
}
public final int getBufferEnd(){
return myBufferEnd;
}
public int getSmartUpdateShift() {
return myJavaLexer.getSmartUpdateShift();
}
private void locateToken(){
if (myTokenType != null) return;
if (myCurOffset >= myBufferEnd) return;
int state = 0; // 0 -- start/end
// 1 -- start of escape in the string start
// 2 -- escape start inside string
// 3 -- inside string
// 4 -- error
int offset = myCurOffset;
do{
char c = myBuffer[offset];
switch(c){
case '\\':
state += state % 2 == 0 ? 1 : -1;
if(state % 5 == 0) state = 4;
case '"':
case '\'':
if((state == 1 || state == 2) && c == mySurroundingQuote){
state = 6 - state * 3 ;
offset++;
break;
}
default:
offset+=state > 0 ? 1 : 0;
break;
case '\n':
case '\r':
state = 0; // break string at the end of line
//offset++;
break;
}
if(offset == myBufferEnd - 1) state = 0;
switch (state){
case 0:
if(offset == myCurOffset){
myJavaLexer.start(myBuffer, myCurOffset, myBufferEnd);
myTokenType = myJavaLexer.getTokenType();
myTokenEnd = myJavaLexer.getTokenEnd();
}
else {
myTokenType = myTokenType = mySurroundingQuote == '"' ? JavaTokenType.STRING_LITERAL : JavaTokenType.CHARACTER_LITERAL;
myTokenEnd = offset;
}
break;
case 4:
myTokenType = JavaTokenType.BAD_CHARACTER;
myTokenEnd = offset;
state = 0;
}
}
while (state > 0);
}
}