|
What this is
This file is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Other links
The source code
/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.editor.ext.java;
import java.util.*;
import javax.swing.text.BadLocationException;
import org.netbeans.editor.TokenContextPath;
import org.netbeans.editor.TokenID;
import org.netbeans.editor.ext.ExtSyntaxSupport;
import org.openide.ErrorManager;
/**
* Support methods for syntax analyzes working with java JMI interfaces.
*
* @author Dusan Balek, Martin Roskanin
* @version 1.00
*/
class JavaDeclarationProcessor
implements ExtSyntaxSupport.DeclarationTokenProcessor,
ExtSyntaxSupport.VariableMapTokenProcessor {
// Internal java declaration token processor states (in the state variable
private static final int INIT = 0; // nothing recognized yet
private static final int TYPE_VAR = 1; // initial datatype or variable already recognized
private static final int TYPE_EXP = 2; // active type expression recognition in progress
private static final int VAR_EXP = 3; // active variable declaration in progress
private static final int EQ_EXP = 4; // "type var = " was recognized and now in after "=" exp
// JCExpression constants
private static final int VARIABLE = JCExpression.VARIABLE;
private static final int DOT = JCExpression.DOT;
private static final int DOT_OPEN = JCExpression.DOT_OPEN;
private static final int ARRAY_OPEN = JCExpression.ARRAY_OPEN;
private static final int ARRAY = JCExpression.ARRAY;
private static final int PARENTHESIS_OPEN = JCExpression.PARENTHESIS_OPEN;
private static final int PARENTHESIS = JCExpression.PARENTHESIS;
private static final int TYPE = JCExpression.TYPE;
private static final int GENERIC_TYPE = JCExpression.GENERIC_TYPE;
private static final int GENERIC_TYPE_OPEN = JCExpression.GENERIC_TYPE_OPEN;
// Invlaid value marking no expression on the given stack position for peekExp()
private static final int NO_EXP = -1;
/** Internal state of recognition engine. */
private int state;
/** Stack of the expressions related to declarations recognition. */
private List expStack = new ArrayList();
/** Type expression of the declaration being recognized. */
private JCExpression typeExp;
/** Support backing this declaration recognizer. */
private JavaSyntaxSupport sup;
/** Position of the begining of the declaration to be returned */
private int decStartPos = -1;
/**
* Absolute offset of the initial variable or type name of declaration.
* The appropriate JCExpression gets created later
* once another token gets recognized and there
* is still a probability that a real declaration was found.
*/
private int typeVarTokenOffset;
/**
* Length of the initial variable or type name. The appropriate JCExpression
* gets created later once another token gets recognized and there
* is still a probability that a real declaration was found.
*/
private int typeVarTokenLength;
/**
* State whether the initial variable is a primitive datatype.
*/
private TokenID typeVarTokenID;
/** Currently inside parenthesis, i.e. comma delimits declarations */
private int parenDepth;
private TokenID curTokenID;
private int curTokenPosition;
private int curTokenLength;
private char[] buffer;
private int bufferStartPos;
/** Variable name to be recognized when operating in a single variable mode. */
private String varName;
/**
* Map filled with the [varName, TypeResolver] pairs.
*/
private StackedMap varMap;
private boolean forScope;
private int forScopeParenDepth;
/** Construct new token processor
* @param varName it contains valid varName name or null to search
* for all variables and construct the variable map.
*/
JavaDeclarationProcessor(JavaSyntaxSupport sup, String varName) {
this.sup = sup;
this.varName = varName;
if (varName == null) {
varMap = new StackedMap();
}
}
/**
* Return integer offset corresponding to the begining
* of the declaration of the requested variable name.
*/
public int getDeclarationPosition() {
return decStartPos;
}
/**
* Return map containing [varName, JavaSyntaxSupport.JavaVariable] pairs
* where typeResolver allows lazy resolving of the variable's type
* by using {@link #resolveType(Object)}.
*/
public Map getVariableMap() {
return varMap;
}
private void clearStack() {
expStack.clear();
}
/** Push exp to top of stack */
private void pushExp(JCExpression exp) {
expStack.add(exp);
}
/** Pop exp from top of stack */
private JCExpression popExp() {
int cnt = expStack.size();
return (cnt > 0) ? (JCExpression)expStack.remove(cnt - 1) : null;
}
/** Look at the exp at top of stack */
private JCExpression peekExp() {
int cnt = expStack.size();
return (cnt > 0) ? (JCExpression)expStack.get(cnt - 1) : null;
}
/** Look at the second exp on stack */
private JCExpression peekExp2() {
int cnt = expStack.size();
return (cnt > 1) ? (JCExpression)expStack.get(cnt - 2) : null;
}
/** Look at the third exp on stack */
private JCExpression peekExp(int ind) {
int cnt = expStack.size();
return (cnt >= ind) ? (JCExpression)expStack.get(cnt - ind) : null;
}
private JCExpression createTokenExp(int id) {
JCExpression exp = new JCExpression(id);
addTokenTo(exp);
return exp;
}
/** Add the token to a given expression */
private void addTokenTo(JCExpression exp) {
exp.addToken(curTokenID, curTokenPosition, getTokenText(curTokenPosition, curTokenLength));
}
private int getValidExpID(JCExpression exp) {
return (exp != null) ? exp.getExpID() : NO_EXP;
}
private void pushTypeVar() {
if (state != TYPE_VAR) {
throw new IllegalArgumentException();
}
state = TYPE_EXP; // var or type will be pushed to stack
int expType;
TokenID id;
if (typeVarTokenID != null) {
expType = JCExpression.TYPE;
id = typeVarTokenID;
} else { // Variable
expType = JCExpression.VARIABLE;
id = JavaTokenContext.IDENTIFIER;
}
JCExpression exp = new JCExpression(expType);
exp.addToken(id, typeVarTokenOffset,
getTokenText(typeVarTokenOffset, typeVarTokenLength));
pushExp(exp); // push initial exp on the stack
}
private void reset() {
state = INIT;
clearStack();
typeExp = null;
}
/**
* Form the type expression.
*
* @return true if the expression was formed successfully
* or false if not (reset() will be called in that case).
*/
private boolean formTypeExp() {
if (expStack.size() == 1) { // must be exactly one exp on stack
typeExp = popExp();
switch (typeExp.getExpID()) {
case ARRAY_OPEN:
case DOT_OPEN:
reset();
return false;
default:
state = VAR_EXP; // start forming variable expression
return true;
}
} else { // more than one exp on stack -> incomplete exp
reset();
return false;
}
}
/**
* Create variable expression.
*
* @param lastVar true if this formed variable is the last one
* (is followed e.g. by semicolon) or whether there can be more variables
* (such as after comma) which will assign TYPE_EXP state.
*
* @return true if variable expression formed successfully
* from the information on the stack
* or false if not (reset() will be called in that case).
*/
private boolean formVarExp(boolean lastVar) {
JCExpression varExp;
if (expStack.size() == 1) { // must be exactly one exp on stack
// leave state == VAR_EXP
varExp = popExp(); // stack will be empty
if (varExp != null) { // formed successfully
switch (varExp.getExpID()) {
case VARIABLE:
case ARRAY:
break; // leave varExp assigned to non-null
default:
varExp = null;
break;
}
}
} else { // more than one exp on stack -> incomplete exp
varExp = null;
}
if (varExp != null) {
processDeclaration(typeExp, varExp);
if (lastVar) {
reset();
} else { // not last var
// Continue to be in VAR_EXP state
// Stack already empty from previous popExp()
}
return true;
} else {
reset();
return false;
}
}
private String getTokenText(int offset, int length) {
try {
return sup.getDocument().getText(offset, length);
} catch (BadLocationException e) {
ErrorManager.getDefault().notify(e);
return "";
}
}
private void processDeclaration(JCExpression typeExp, JCExpression varExp) {
if (varName == null) { // collect all variables
String varName = getVarName(varExp);
JavaVar javaVar = new JavaVar(typeExp, varExp);
varMap.put(varName, javaVar);
} else if (varName.equals(getVarName(varExp))) { // found var of the requested name
decStartPos = typeVarTokenOffset;
}
}
private String getVarName(JCExpression varExp) {
switch (varExp.getExpID()) {
case VARIABLE:
return varExp.getTokenText(0);
case ARRAY:
JCExpression var = varExp.getParameter(0); // variable of the array
return var.getTokenText(0);
default:
throw new IllegalStateException();
}
}
public boolean token(TokenID tokenID, TokenContextPath tokenContextPath,
int tokenOffset, int tokenLen) {
int pos = bufferStartPos + tokenOffset;
curTokenID = tokenID;
curTokenPosition = pos;
curTokenLength = tokenLen;
// Check whether we are really recognizing the java tokens
if (!tokenContextPath.contains(JavaTokenContext.contextPath)) {
state = INIT;
return true;
}
switch (tokenID.getNumericID()) {
case JavaTokenContext.BOOLEAN_ID:
case JavaTokenContext.BYTE_ID:
case JavaTokenContext.CHAR_ID:
case JavaTokenContext.DOUBLE_ID:
case JavaTokenContext.FLOAT_ID:
case JavaTokenContext.INT_ID:
case JavaTokenContext.LONG_ID:
case JavaTokenContext.SHORT_ID:
if (parenDepth <= 1) { // no parens or in method declaration parms
switch (state) {
case INIT:
typeVarTokenOffset = pos;
typeVarTokenLength = tokenLen;
typeVarTokenID = tokenID;
state = TYPE_VAR;
break;
case TYPE_VAR: // var-or-type type => invalid
case TYPE_EXP: // something followed by datatype => invalid
case VAR_EXP: // varName followed by datatype => invalid
reset();
break;
case EQ_EXP: // in expression after "type var = "
// do nothing - leave the EQ_EXP state
break;
default:
throw new IllegalStateException();
}
} // else -> in parens -> do nothing
break;
case JavaTokenContext.FOR_ID:
if (varMap != null) {
varMap.pushNewScope();
forScope = true;
}
break;
case JavaTokenContext.IDENTIFIER_ID:
if (parenDepth <= 1) { // no parens or in method declaration parms
switch (state) {
case INIT:
typeVarTokenOffset = pos;
typeVarTokenLength = tokenLen;
typeVarTokenID = null;
state = TYPE_VAR;
break;
case TYPE_VAR: // var-or-type ident => maybe declaration
pushTypeVar();
// continue to TYPE_EXP handling
case TYPE_EXP: // something followed by ident => varName
JCExpression top = peekExp();
switch (getValidExpID(top)) {
case VARIABLE: // var "ident" -> decl
case TYPE: // "int" "ident" -> decl
case DOT: // var1.var2. ... var-n "ident"
case ARRAY: // "array[]" "ident"
case GENERIC_TYPE: // List "ident"
if (formTypeExp()) { // formed successfully
// start to form variable expression
pushExp(createTokenExp(VARIABLE));
}
break;
case DOT_OPEN: // closing dot expr.
top.setExpID(DOT);
top.addParameter(createTokenExp(VARIABLE));
break;
case GENERIC_TYPE_OPEN: //
pushExp(createTokenExp(VARIABLE));
break;
default:
reset();
break;
}
break;
case VAR_EXP: // unclosed var decl. followed by ident -> invalid
if (expStack.size() == 0) { // nothing on stack
// This can happen after comma that was separating
// two variables of the same type
pushExp(createTokenExp(VARIABLE));
} else { // invalid "var" "var" (or e.g. "var[]" "var")
reset();
}
break;
case EQ_EXP: // in expression after "type var = "
// do nothing - leave the EQ_EXP state
break;
default:
throw new IllegalStateException();
}
} // else -> in parens -> do nothing
break;
case JavaTokenContext.DOT_ID:
if (parenDepth <= 1) { // no parens or in method declaration parms
switch (state) {
case INIT: // dot in initial state -> do nothing
break;
case TYPE_VAR: // var-or-type "." -> open dot
pushTypeVar();
// continue to TYPE_EXP handling
case TYPE_EXP:
JCExpression top = peekExp();
switch (getValidExpID(top)) {
case VARIABLE: // var "." -> DOT_OPEN
case GENERIC_TYPE: // "C1.C2" -> DOT_OPEN
popExp(); // pop var
JCExpression opExp = createTokenExp(DOT_OPEN);
opExp.addParameter(top);
pushExp(opExp);
break;
case DOT: // var1.var2. ... var-n "."
top.setExpID(DOT_OPEN);
break;
default:
reset();
break;
}
break;
case VAR_EXP: // "type var." -> reset
reset();
break;
case EQ_EXP: // in expression after "type var = "
// do nothing - leave the EQ_EXP state
break;
default:
throw new IllegalStateException();
}
} // else -> in parens -> do nothing
break;
case JavaTokenContext.LBRACKET_ID: // "["
if (parenDepth <= 1) { // no parens or in method declaration parms
switch (state) {
case INIT: // '[' in initial state -> do nothing
break;
case TYPE_VAR: // var-or-type "[" -> open array
pushTypeVar();
// continue to TYPE_EXP handling
case TYPE_EXP:
{
JCExpression top = peekExp();
switch (getValidExpID(top)) {
case DOT: // var1.var2. ... var-n "["
case VARIABLE: // var "[" -> ARRAY_OPEN
case TYPE:
case GENERIC_TYPE: // e.g. "List" "[" -> ARRAY_OPEN
popExp(); // pop var
JCExpression opExp = createTokenExp(ARRAY_OPEN);
opExp.addParameter(top);
pushExp(opExp);
break;
case ARRAY: // array[] "[" -> sub-ARRAY_OPEN again
top.setExpID(ARRAY_OPEN);
addTokenTo(top);
break;
default:
reset();
break;
}
break;
}
case VAR_EXP: // e.g. "int a" "[" -> ARRAY_OPEN
{
JCExpression top = peekExp();
switch (getValidExpID(top)) {
case VARIABLE: // var "[" -> ARRAY_OPEN
popExp(); // pop var
JCExpression opExp = createTokenExp(ARRAY_OPEN);
opExp.addParameter(top);
pushExp(opExp);
break;
case ARRAY: // array[] "[" -> sub-ARRAY_OPEN again
top.setExpID(ARRAY_OPEN);
addTokenTo(top);
default:
reset();
break;
}
break;
}
case EQ_EXP: // in expression after "type var = "
// do nothing - leave the EQ_EXP state
break;
default:
throw new IllegalStateException();
}
} // else -> in parens -> do nothing
break;
case JavaTokenContext.ELLIPSIS_ID: // "..."
if (parenDepth <= 1) { // no parens or in method declaration parms
switch (state) {
case INIT: // '[' in initial state -> do nothing
break;
case TYPE_VAR: // var-or-type "..." -> array
pushTypeVar();
// continue to TYPE_EXP handling
case TYPE_EXP:
{
JCExpression top = peekExp();
switch (getValidExpID(top)) {
case DOT: // var1.var2. ... var-n "..." -> ARRAY
case VARIABLE: // var "..." -> ARRAY
case TYPE: // int "..." -> ARRAY
case GENERIC_TYPE: // e.g. "List" "..." -> ARRAY
popExp(); // pop var
JCExpression opExp = createTokenExp(ARRAY);
// Add "..." again to have the even token count like with "[" "]"
addTokenTo(opExp);
opExp.addParameter(top);
pushExp(opExp);
break;
case ARRAY: // array[] "[" -> sub-ARRAY_OPEN again
addTokenTo(top);
// Add "..." again to have the even token count like with "[" "]"
addTokenTo(top);
break;
default:
reset();
break;
}
break;
}
case VAR_EXP: // e.g. "int a" "..." -> ARRAY_OPEN
reset();
break;
case EQ_EXP: // in expression after "type var = "
// do nothing - leave the EQ_EXP state
break;
default:
throw new IllegalStateException();
}
} // else -> in parens -> do nothing
break;
case JavaTokenContext.RBRACKET_ID: // "]"
if (parenDepth <= 1) { // no parens or in method declaration parms
switch (state) {
case INIT: // ']' in initial state -> do nothing
break;
case TYPE_VAR: // var-or-type "]" -> error
reset();
break;
case TYPE_EXP:
{
JCExpression top = peekExp();
switch (getValidExpID(top)) {
case ARRAY_OPEN: // "type[" "]" -> ARRAY
addTokenTo(top);
top.setExpID(ARRAY);
break;
default:
reset();
break;
}
break;
}
case VAR_EXP: // e.g. "int a[" "]" -> ARRAY
{
JCExpression top = peekExp();
switch (getValidExpID(top)) {
case ARRAY_OPEN: // type var[ "]" -> ARRAY
addTokenTo(top);
top.setExpID(ARRAY);
break;
default:
reset();
break;
}
break;
}
case EQ_EXP: // in expression after "type var = "
// do nothing - leave the EQ_EXP state
break;
default:
throw new IllegalStateException();
}
} // else -> in parens -> do nothing
break;
case JavaTokenContext.LT_ID: // "<"
{
if (parenDepth <= 1) { // no parens or in method declaration parms
switch (state) {
case TYPE_VAR:
pushTypeVar();
// continue to TYPE_EXP handling
case TYPE_EXP:
JCExpression top = peekExp();
switch (getValidExpID(top)) {
case VARIABLE:
case DOT:
popExp(); // pop the top expression
JCExpression genExp = createTokenExp(GENERIC_TYPE_OPEN);
genExp.addParameter(top);
pushExp(genExp);
break;
default:
// could possibly still be acceptable as operator '<'
break;
}
break;
case EQ_EXP: // in expression after "type var = "
// do nothing - leave the EQ_EXP state
break;
default:
reset();
break;
}
} // else - inside parens inside the exp after "="
break;
}
case JavaTokenContext.GT_ID: // ">"
{
if (parenDepth <= 1) { // no parens or in method declaration parms
switch (state) {
case TYPE_VAR:
pushTypeVar();
// continue to TYPE_EXP handling
case TYPE_EXP:
JCExpression top = peekExp();
switch (getValidExpID(top)) {
case VARIABLE:
case ARRAY:
case DOT:
case GENERIC_TYPE:
JCExpression top2 = peekExp2();
switch (getValidExpID(top2)) {
case GENERIC_TYPE_OPEN:
popExp(); // pop the top expression
top2.addParameter(top);
top2.setExpID(GENERIC_TYPE);
addTokenTo(top2);
top = top2;
break;
default:
reset();
break;
}
break;
default:
reset();
break;
}
break;
case EQ_EXP: // in expression after "type var = "
// do nothing - leave the EQ_EXP state
break;
default:
reset();
break;
}
} // else - inside parens inside the exp after "="
break;
}
case JavaTokenContext.RSSHIFT_ID: // ">>"
{
if (parenDepth <= 1) { // no parens or in method declaration parms
switch (state) {
case TYPE_VAR:
pushTypeVar();
// continue to TYPE_EXP handling
case TYPE_EXP:
JCExpression top = peekExp();
switch (getValidExpID(top)) {
case VARIABLE:
case DOT:
case GENERIC_TYPE:
JCExpression top2 = peekExp2();
switch (getValidExpID(top2)) {
case GENERIC_TYPE_OPEN:
// Check whether outer is open as well
JCExpression top3 = peekExp(3);
if (getValidExpID(top3) == GENERIC_TYPE_OPEN) {
popExp();
top2.addParameter(top);
top2.setExpID(GENERIC_TYPE);
addTokenTo(top2); // [TODO] revise possible spliting of the token
popExp();
top3.addParameter(top2);
top3.setExpID(GENERIC_TYPE);
addTokenTo(top3); // [TODO] revise possible spliting of the token
} else { // inner is not generic type
reset();
}
break;
default:
reset();
break;
}
break;
default:
reset();
break;
}
break;
case EQ_EXP: // in expression after "type var = "
// do nothing - leave the EQ_EXP state
break;
default:
reset();
break;
}
} // else - inside parens inside the exp after "="
break;
}
case JavaTokenContext.RUSHIFT_ID: // ">>>"
{
if (parenDepth <= 1) { // no parens or in method declaration parms
switch (state) {
case TYPE_VAR:
pushTypeVar();
// continue to TYPE_EXP handling
case TYPE_EXP:
JCExpression top = peekExp();
switch (getValidExpID(top)) {
case VARIABLE:
case DOT:
case GENERIC_TYPE:
JCExpression top2 = peekExp2();
switch (getValidExpID(top2)) {
case GENERIC_TYPE_OPEN:
// Check whether outer is open as well
JCExpression top3 = peekExp(3);
JCExpression top4 = peekExp(4);
if (getValidExpID(top3) == GENERIC_TYPE_OPEN
&& getValidExpID(top4) == GENERIC_TYPE_OPEN
) {
popExp();
top2.addParameter(top);
top2.setExpID(GENERIC_TYPE);
addTokenTo(top2); // [TODO] revise possible spliting of the token
popExp();
top3.addParameter(top2);
top3.setExpID(GENERIC_TYPE);
addTokenTo(top3); // [TODO] revise possible spliting of the token
popExp();
top4.addParameter(top3);
top4.setExpID(GENERIC_TYPE);
addTokenTo(top4); // [TODO] revise possible spliting of the token
} else { // inner is not generic type
reset();
}
break;
default:
reset();
break;
}
break;
default:
reset();
break;
}
break;
case EQ_EXP: // in expression after "type var = "
// do nothing - leave the EQ_EXP state
break;
default:
reset();
break;
}
} // else - inside parens inside the exp after "="
break;
}
case JavaTokenContext.LPAREN_ID: // "("
switch (state) {
case TYPE_VAR:
pushTypeVar();
// continue to TYPE_EXP handling
case TYPE_EXP:
case VAR_EXP: // unclosed var decl. followed by ident -> invalid
case INIT:
reset();
break;
case EQ_EXP: // in expression after "type var = "
break;
default:
throw new IllegalStateException();
}
// In all cases increase the parenthesis depth
parenDepth++;
if (forScope)
forScopeParenDepth++;
break;
case JavaTokenContext.RPAREN_ID: // ")"
switch (state) {
case TYPE_VAR:
pushTypeVar();
// continue to TYPE_EXP handling
case TYPE_EXP:
case INIT:
reset();
break;
case VAR_EXP: // unclosed var decl. followed by ident -> invalid
if (parenDepth == 1) { // method declaration end?
formVarExp(true);
} else {
reset();
}
break;
case EQ_EXP: // in expression after "type var = "
break;
default:
throw new IllegalStateException();
}
// // In all cases decrease the parenthesis depth
if (parenDepth > 0) {
parenDepth--;
}
if (forScope && forScopeParenDepth > 0) {
forScopeParenDepth--;
}
break;
case JavaTokenContext.LBRACE_ID: // "{" treated as cmd sep.
reset();
parenDepth = 0; // Reset the parenthesis depth to zero
if (!forScope && varMap != null)
varMap.pushNewScope();
forScope = false;
break;
case JavaTokenContext.RBRACE_ID: // "}" treated as cmd sep.
reset();
parenDepth = 0; // Reset the parenthesis depth to zero
if (varMap != null)
varMap.removeScope();
break;
case JavaTokenContext.SEMICOLON_ID: // ';' treated as cmd sep.
if (forScope && forScopeParenDepth == 0) {
if (varMap != null)
varMap.removeScope();
forScope = false;
}
switch (state) {
case VAR_EXP:
formVarExp(true);
break;
default:
reset();
break;
}
break;
case JavaTokenContext.COMMA_ID:
if (parenDepth <= 1) { // no parens or in method declaration parms
switch (state) {
case TYPE_EXP:
JCExpression top2 = peekExp2();
if (getValidExpID(top2) == GENERIC_TYPE_OPEN) {
JCExpression top = peekExp();
switch (getValidExpID(top)) {
case VARIABLE:
case DOT:
case GENERIC_TYPE:
popExp();
top2.addParameter(top);
addTokenTo(top2); // add "," to open generics type
break;
default:
reset();
break;
}
} else { // not open generics
// and not followed by identifier so it can't be
// param separator in parenDepth == 1 as well
reset();
}
break;
case VAR_EXP:
// can either be "int var1, var2" or m1(int i, String s)
formVarExp(parenDepth == 1);
break;
case EQ_EXP: // in expression after "type var = "
if (parenDepth == 0) { // separates variable expressions
state = VAR_EXP; // expect next variable
} // else - commas e.g. in "type var = method(a, b, c)" => do nothing
break;
default:
reset();
break;
}
} // else -> in parens -> do nothing
break;
case JavaTokenContext.EQ_ID:
if (parenDepth <= 1) {
switch (state) {
case VAR_EXP:
formVarExp(false);
state = EQ_EXP;
break;
case EQ_EXP: // in expression after "type var = "
// do nothing - leave the EQ_EXP state
break;
default:
reset();
break;
}
} // else -> in parens -> do nothing
break;
case JavaTokenContext.WHITESPACE_ID: // whitespace ignored
case JavaTokenContext.LINE_COMMENT_ID: // line comment ignored
case JavaTokenContext.BLOCK_COMMENT_ID: // block comment ignored
break;
case JavaTokenContext.COLON_ID: // 1.5 enhanced for loop sysntax
if (parenDepth <= 1) {
switch (state) {
case VAR_EXP:
formVarExp(true); // no more vars after ":" (in foreach only?)
break;
case EQ_EXP: // in expression after "type var = "
// do nothing - leave the EQ_EXP state
break;
default:
reset();
break;
}
} // else -> in parens -> do nothing
break;
default:
}
return true;
}
public int eot(int offset) {
return 0;
}
public void nextBuffer(char[] buffer, int offset, int len,
int startPos, int preScan, boolean lastBuffer) {
this.buffer = buffer;
bufferStartPos = startPos - offset;
}
private static class JavaVar implements JavaSyntaxSupport.JavaVariable {
private JCExpression typeExp;
private JCExpression varExp;
JavaVar(JCExpression typeExp, JCExpression varExp) {
this.typeExp = typeExp;
this.varExp = varExp;
}
public JCExpression getTypeExpression() {
return typeExp;
}
public JCExpression getVariableExpression() {
return varExp;
}
public String toString() {
return "TYPE:\n" + typeExp + "\nVAR:\n" + varExp; // NOI18N
}
}
private static class StackedMap implements Map {
private Stack stack;
private StackedMap() {
stack = new Stack();
}
public int size() {
int size = 0;
for (Iterator it = stack.iterator(); it.hasNext();) {
size += ((Map)it.next()).size();
}
return size;
}
public boolean isEmpty() {
for (Iterator it = stack.iterator(); it.hasNext();) {
if (!((Map)it.next()).isEmpty())
return false;
}
return true;
}
public boolean containsKey(Object key) {
for (Iterator it = stack.iterator(); it.hasNext();) {
if (((Map)it.next()).containsKey(key))
return true;
}
return false;
}
public boolean containsValue(Object value) {
for (Iterator it = stack.iterator(); it.hasNext();) {
if (((Map)it.next()).containsValue(value))
return true;
}
return false;
}
public Object get(Object key) {
for (Iterator it = stack.iterator(); it.hasNext();) {
Object o = ((Map)it.next()).get(key);
if (o != null)
return o;
}
return null;
}
public Object put(Object key, Object value) {
if (stack.isEmpty())
pushNewScope();
return ((Map)stack.peek()).put(key, value);
}
public Object remove(Object key) {
for (Iterator it = stack.iterator(); it.hasNext();) {
Object o = ((Map)it.next()).remove(key);
if (o != null)
return o;
}
return null;
}
public void putAll(Map t) {
if (stack.isEmpty())
pushNewScope();
((Map)stack.peek()).putAll(t);
}
public void clear() {
for (Iterator it = stack.iterator(); it.hasNext();) {
((Map)it.next()).clear();
}
}
public Set keySet() {
Set set = new TreeSet();
for (Iterator it = stack.iterator(); it.hasNext();) {
set.addAll(((Map)it.next()).keySet());
}
return set;
}
public Collection values() {
Collection col = new ArrayList();
for (Iterator it = stack.iterator(); it.hasNext();) {
col.addAll(((Map)it.next()).values());
}
return col;
}
public Set entrySet() {
Set set = new HashSet();
for (Iterator it = stack.iterator(); it.hasNext();) {
set.addAll(((Map)it.next()).entrySet());
}
return set;
}
public void pushNewScope() {
stack.push(new HashMap());
}
public void removeScope() {
if (!stack.isEmpty())
stack.pop();
}
}
}
|