blob: 5f63f803de322736e996f5d45fe35c3c2159e173 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
/*
* $RCSfile: Expression.java,v $
* $Revision: 1.5 $ $Date: 2005/02/15 22:53:46 $
*/
package org.eclipse.jem.internal.proxy.core;
import java.text.MessageFormat;
import java.util.ArrayList;
import org.eclipse.jem.internal.proxy.initParser.tree.*;
/**
* This is an internal implementation of Expression. It encapsulates much of the processing required
* into a common form that will be turned into simple push/pop/evaluate type of interaction with the
* actual other side.
* <p>
* It will maintain a stack of the expressions. As the expressions come in they will be stacked if not
* able to be executed immediately. The expressions come to this class in an outside to inside order,
* but they need to be processed in an inside-out order instead.
* <p>
* Subclasses will be used for the different types of proxy interfaces. The abstract methods will
* then be the simple interface.
* <p>
* It is not meant to override the actual create expression methods because the processing the stack
* is very sensitive and must execute in the proper sequence. So the create methods are final for this.
* <p>
* This class is not thread-safe.
*
* @since 1.0.0
*/
public abstract class Expression implements IExpression {
/*
* We have stack here, but rather than create a class that does the
* stack protocol, will simply have some private methods to do
* the same thing for the stack. (Note: Can't use java.util.Stack
* because that is a synchronized class, and don't want the overhead).
*
* The purpose of the stack is to stack up expressions that have not yet
* been evaluated.
*
* Each expression type will control the content of what it pushes and pops.
* The expression type will be the last thing it pushes so that on popping
* we know what kind of expression is now completed and ready for evaluation.
*/
private ArrayList controlStack = new ArrayList(30);
protected final ProxyFactoryRegistry registry;
protected final IStandardBeanProxyFactory beanProxyFactory;
/**
* Push an object onto the control stack.
*
* @param o
*
* @since 1.0.0
*/
protected final void push(Object o) {
controlStack.add(o);
}
/**
* Pop an object off of the control stack
* @return
*
* @since 1.0.0
*/
protected final Object pop() {
return controlStack.remove(controlStack.size()-1);
}
/**
* Peek at an object from the control stack. <code>fromTop</code> is how far from the top of the stack to look.
* If it one, then it is the top entry, two is the next one down. Zero is an invalid value for the parameter.
* @param fromTop How far from the top to peek. <code>1</code> is the top, not zero.
* @return
*
* @since 1.0.0
*/
protected final Object peek(int fromTop) {
// 1 means the top, 2 is the next one down.
return controlStack.get(controlStack.size()-fromTop);
}
/*
* Expression type constants.
*/
/*
* ARRAY ACCESS expression.
* The expression stack will have:
* IExpression.ARRAYACCESS_ARRAY
* IExpression.ARRAYACCESS_INDEX (for 1 to n times depending on index count)
* PROCESS_EXPRESSION
*
* The value stack will have
* ARRAYACCESS
* Integer(index count)
*/
private static final Integer ARRAYACCESS = new Integer(IInternalExpressionConstants.ARRAY_ACCESS_EXPRESSION);
private static final Integer ARRAYACCESS_INDEX_1 = new Integer(1); // Use in normal case of one index count. Saves object creation.
/*
* ARRAY CREATION expression.
* The expression stack will have:
* ARRAYCREATION_INITIALIZER - if hasInitializer
* IExpression.ARRAYCREATION_DIMENSION (for 0 to n times depending on dimension count)
* PROCESS_EXPRESSION
*
* The value stack will have
* ARRAYCREATION
* type (either a string representing the type, or an IBeanProxyType representing the type).
* Integer(dimension count) (if zero then there is an initializer)
*
*
* Note: Array Initializer works with this in that it will peek into the value stack two entries down
* to find the type of array it should be creating.
*/
private static final Integer ARRAYCREATION = new Integer(IInternalExpressionConstants.ARRAY_CREATION_EXPRESSION);
private static final Integer ARRAY_CREATION_DIMENSION_1 = new Integer(1); // Use in normal case of one dimension. Save object creation.
private static final Integer ARRAY_CREATION_DIMENSION_0 = new Integer(0); // Use in normal case of initializer. Save object creation.
private static final int ARRAY_INITIALIZER = -1; // Local because only needed her for expression.
/*
* ARRAY INITIALIZER expression
* The expression stack will have:
* IExpression.ARRAYINITIALIZER_EXPRESSION (for n times depending on number of expressions count)
* PROCESS_EXPRESSION
*
* The value stack will have
* ARRAYINITIALIZER
* type (either a string representing the type, or an IBeanProxyType representing the type).
* I.e. if array being created is int[][], the value pushed here will be int[]. This is because when created
* the array will wind up with int[expressioncount][] in the end.
* Integer (expression count)
*
* Note: Imbedded Array Initializers works with this in that it will peek into the value stack two entries down
* to find the type of array it should be creating.
*/
private static final Integer ARRAYINITIALIZER = new Integer(IInternalExpressionConstants.ARRAY_INITIALIZER_EXPRESSION);
private static final Integer ARRAYINITIALIZER_COUNT_0 = new Integer(0); // Use in normal case of empty array. Save object creation.
private static final Integer ARRAYINITIALIZER_COUNT_1 = new Integer(1); // Use in normal case of one element array. Save object creation.
private static final Integer ARRAYINITIALIZER_COUNT_2 = new Integer(2); // Use in normal case of two element array. Save object creation.
/*
* CAST expression.
* The expression stack will have:
* IExpression.CAST_EXPRESSION
* PROCESS_EXPRESSION
*
* The value stack will have:
* CAST
* type (either a string representing the type, or an IBeanProxyType representing the type).
*/
private static final Integer CAST = new Integer(IInternalExpressionConstants.CAST_EXPRESSION);
/*
* CLASS INSTANCE CREATION expression.
* The expression stack will have:
* IExpression.CLASSINSTANCECREATION_ARGUMENT (for 0 to n times depending on argument count)
* PROCESS_EXPRESSION
*
* The value stack will have
* CLASSINSTANCECREATION
* type (either a string representing the type, or an IBeanProxyType representing the type).
* Integer(argument count)
*
*
* Note: Array Initializer works with this in that it will peek into the value stack two entries down
* to find the type of array it should be creating.
*/
private static final Integer CLASSINSTANCECREATION = new Integer(IInternalExpressionConstants.CLASS_INSTANCE_CREATION_EXPRESSION);
private static final Integer CLASS_INSTANCE_CREATION_ARGUMENTS_1 = new Integer(1); // Use in normal case of one argument. Save object creation.
private static final Integer CLASS_INSTANCE_CREATION_ARGUMENTS_0 = new Integer(0); // Use in normal case of no arguments (default ctor). Save object creation.
/*
* CONDITIONAL expression.
* Since this can cause skipping of expressions (e.g. if condition is false, then the true condition should not be evaluated),
* we need to have a process expression and process call to the other side for each expression so that it can
* determine if it should be ignored or not.
*
* The expression stack will have:
* IExpression.CONDITIONAL_CONDITION
* PROCESS_EXPRESSION
* IExpression.CONDITIONAL_TRUE
* PROCESS_EXPRESSION
* IExpression.CONDITIONAL_FALSE
* PROCESS_EXPRESSION
*
* The value stack will have:
* CONDITIONAL
* CONDITIONAL_CONDITION
* CONDITIONAL
* CONDITIONAL_TRUE
* CONDITIONAL
* CONDITIONAL_FALSE
*
*/
private static final Integer CONDITIONAL = new Integer(IInternalExpressionConstants.CONDITIONAL_EXPRESSION);
private static final Integer CONDITIONAL_TEST = new Integer(IExpressionConstants.CONDITIONAL_CONDITION);
private static final Integer CONDITIONAL_TRUEEXP = new Integer(IExpressionConstants.CONDITIONAL_TRUE);
private static final Integer CONDITIONAL_FALSEXP = new Integer(IExpressionConstants.CONDITIONAL_FALSE);
/*
* PREFIX expression.
* The expression stack will have:
* IExpression.PREFIX_OPERAND
* PROCESS_EXPRESSION
*
* The value stack will have:
* PREFIX
* operator (using Integer prefix operator constants defined here)
*/
private static final Integer PREFIX = new Integer(IInternalExpressionConstants.PREFIX_EXPRESSION);
private static final Integer[] PREFIX_OPERATORS;
static {
PREFIX_OPERATORS = new Integer[IExpressionConstants.PRE_MAX+1];
PREFIX_OPERATORS[IExpressionConstants.PRE_PLUS] = new Integer(IExpressionConstants.PRE_PLUS);
PREFIX_OPERATORS[IExpressionConstants.PRE_MINUS] = new Integer(IExpressionConstants.PRE_MINUS);
PREFIX_OPERATORS[IExpressionConstants.PRE_COMPLEMENT] = new Integer(IExpressionConstants.PRE_COMPLEMENT);
PREFIX_OPERATORS[IExpressionConstants.PRE_NOT] = new Integer(IExpressionConstants.PRE_NOT);
}
/*
* INFIX expression.
* Since two types of infix operators (conditional and AND or) can cause skipping of expressions (e.g. once
* conditional and sees a false expression, the rest of the expressions are skipped and should not be evaluated),
* we need to have a process expression and process call to the other side for each expression so that it can
* determine if it should be ignored or not.
*
* The expression stack will have:
* IExpression.INFIX_LEFT
* PROCESS_EXPRESSION
* IExpression.INFIX_RIGHT
* PROCESS_EXPRESSION
* (for 0 to n times depending upon extended count)
* IExpression.INFIX_EXTENDED
* PROCESS_EXPRESSION
*
* The value stack will have:
* INFIX
* operator (using Integer infix operator constants defined here)
* IN_LEFT
* (for (extendedCount) times) This will cover the right one and all but last extended
* INFIX
* operator (using Integer infix operator constants defined here)
* IN_OTHER
* INFIX
* operator (using Integer infix operator constants defined here)
* IN_LAST (this is covers either the right one if no extended, or the last extended)
*/
private static final Integer INFIX = new Integer(IInternalExpressionConstants.INFIX_EXPRESSION);
private static final Integer IN_LEFT = new Integer(IInternalExpressionConstants.INFIX_LEFT_OPERAND);
private static final Integer IN_OTHER= new Integer(IInternalExpressionConstants.INFIX_OTHER_OPERAND);
private static final Integer IN_LAST = new Integer(IInternalExpressionConstants.INFIX_LAST_OPERAND);
private static final Integer[] INFIX_OPERATORS;
static {
INFIX_OPERATORS = new Integer[IExpressionConstants.IN_MAX+1];
INFIX_OPERATORS[IExpressionConstants.IN_AND] = new Integer(IExpressionConstants.IN_AND);
INFIX_OPERATORS[IExpressionConstants.IN_CONDITIONAL_AND] = new Integer(IExpressionConstants.IN_CONDITIONAL_AND);
INFIX_OPERATORS[IExpressionConstants.IN_CONDITIONAL_OR] = new Integer(IExpressionConstants.IN_CONDITIONAL_OR);
INFIX_OPERATORS[IExpressionConstants.IN_DIVIDE] = new Integer(IExpressionConstants.IN_DIVIDE);
INFIX_OPERATORS[IExpressionConstants.IN_EQUALS] = new Integer(IExpressionConstants.IN_EQUALS);
INFIX_OPERATORS[IExpressionConstants.IN_GREATER] = new Integer(IExpressionConstants.IN_GREATER);
INFIX_OPERATORS[IExpressionConstants.IN_GREATER_EQUALS] = new Integer(IExpressionConstants.IN_GREATER_EQUALS);
INFIX_OPERATORS[IExpressionConstants.IN_LEFT_SHIFT] = new Integer(IExpressionConstants.IN_LEFT_SHIFT);
INFIX_OPERATORS[IExpressionConstants.IN_LESS] = new Integer(IExpressionConstants.IN_LESS);
INFIX_OPERATORS[IExpressionConstants.IN_LESS_EQUALS] = new Integer(IExpressionConstants.IN_LESS_EQUALS);
INFIX_OPERATORS[IExpressionConstants.IN_MINUS] = new Integer(IExpressionConstants.IN_MINUS);
INFIX_OPERATORS[IExpressionConstants.IN_NOT_EQUALS] = new Integer(IExpressionConstants.IN_NOT_EQUALS);
INFIX_OPERATORS[IExpressionConstants.IN_OR] = new Integer(IExpressionConstants.IN_OR);
INFIX_OPERATORS[IExpressionConstants.IN_PLUS] = new Integer(IExpressionConstants.IN_PLUS);
INFIX_OPERATORS[IExpressionConstants.IN_REMAINDER] = new Integer(IExpressionConstants.IN_REMAINDER);
INFIX_OPERATORS[IExpressionConstants.IN_RIGHT_SHIFT_SIGNED] = new Integer(IExpressionConstants.IN_RIGHT_SHIFT_SIGNED);
INFIX_OPERATORS[IExpressionConstants.IN_RIGHT_SHIFT_UNSIGNED] = new Integer(IExpressionConstants.IN_RIGHT_SHIFT_UNSIGNED);
INFIX_OPERATORS[IExpressionConstants.IN_TIMES] = new Integer(IExpressionConstants.IN_TIMES);
INFIX_OPERATORS[IExpressionConstants.IN_XOR] = new Integer(IExpressionConstants.IN_XOR);
}
/*
* INSTANCEOF expression.
* The expression stack will have:
* IExpression.INSTANCEOF_EXPRESSION
* PROCESS_EXPRESSION
*
* The value stack will have:
* INSTANCEOF
* type (either a string representing the type, or an IBeanProxyType representing the type).
*/
private static final Integer INSTANCEOF = new Integer(IInternalExpressionConstants.INSTANCEOF_EXPRESSION);
/*
* Field access expression.
* The expression stack will have:
* IExpression.FIELD_RECEIVER (if hasReceiver is true)
* PROCESS_EXPRESSION
*
* The value stack will have:
* FIELDACCESS
* name (the name of the field)
* Boolean (true if has receiver)
*/
private static final Integer FIELDACCESS = new Integer(IInternalExpressionConstants.FIELD_ACCESS_EXPRESSION);
/*
* Method invocation expression.
* The expression stack will have:
* IExpression.METHOD_RECEIVER (if hasReceiver is true)
* IExpression.METHOD_ARGUMENT (0 to n times for how many arguments).
* PROCESS_EXPRESSION
*
* The value stack will have:
* METHODINVOCATION
* name (the name of the method)
* Boolean (true if has receiver)
* argCount (the number of arguments).
*/
private static final Integer METHODINVOCATION = new Integer(IInternalExpressionConstants.METHOD_EXPRESSION);
private static final Integer METHOD_ARGUMENTS_1 = new Integer(1); // Use in normal case of one argument. Save object creation.
private static final Integer METHOD_ARGUMENTS_0 = new Integer(0); // Use in normal case of no arguments. Save object creation.
/*
* Next valid for expression stack. This is kept as a stack also.
* As the expressions come in, the appropriate order (in reverse)
* of expression types will be pushed, and then popped as they
* come in.
*
* Since we can't have an array list of ints, will simulate the
* stack here.
*/
private int[] nextForExpressionStack = new int[30];
private int nextForExpressionStackPos = -1; // Position of top entry in stack.
private static final int INVALID = -2; // Mark that this expression is now invalid. (Goes into nextForExpressionStackSize)
private String invalidMsg = null; // Msg for being invalid if default msg not sufficient.
private static final int PROCESS_EXPRESSION = Integer.MIN_VALUE; // This is pushed onto the next expression stack, and went it is popped, then the expression is complete
/**
* Check the for expression, and if legal, set to the next valid for expression type,
* if it can.
*
* @param forExpression
* @throws IllegalStateException
*
* @since 1.0.0
*/
protected final void checkForExpression(int forExpression) throws IllegalStateException {
if (nextForExpressionStackPos != INVALID) {
if (nextForExpressionStackPos == -1)
if (forExpression == IExpressionConstants.ROOTEXPRESSION)
return; // valid. We are at the root (i.e. nothing is waiting).
else
; // invalid. drop through
else if (nextForExpressionStack[nextForExpressionStackPos--] == forExpression)
return; // Valid, the top expression matched.
} else {
String expMsg = invalidMsg != null ? MessageFormat.format(ProxyMessages.getString("Expression.InInvalidStateDueTo_EXC_"), new Object[] {invalidMsg}) : ProxyMessages.getString("Expression.InInvalidState_EXC_"); //$NON-NLS-1$ //$NON-NLS-2$
throw new IllegalStateException(expMsg);
}
// If we got here, then invalid.
nextForExpressionStackPos = INVALID;
throw new IllegalStateException(ProxyMessages.getString("Expression.TypeSentInInvalidOrder_EXC_")); //$NON-NLS-1$
}
/**
* Peek into the for expression stack to see if the top entry is the passed in value. It will
* not pop the stack nor throw any exceptions.
*
* @param forExpression The top expression flag will be compared against this value.
* @return <code>true</code> if the top expression equals the parameter passed in.
*
* @since 1.0.0
*/
protected final boolean peekForExpression(int forExpression) {
if (nextForExpressionStackPos != INVALID) {
if (nextForExpressionStackPos == -1)
if (forExpression == IExpressionConstants.ROOTEXPRESSION)
return true; // valid. We are at the root (i.e. nothing is waiting).
else
; // invalid. drop through
else if (nextForExpressionStack[nextForExpressionStackPos] == forExpression)
return true; // Valid, the top expression matched.
}
return false;
}
/**
* Mark this expression as now invalid.
*/
protected final void markInvalid() {
nextForExpressionStackPos = INVALID;
controlStack.clear();
closeProxy();
}
/**
* Mark this expression as now invalid, but supply a message to go with it.
*
* @param msg
*
* @since 1.0.0
*/
protected final void markInvalid(String msg) {
invalidMsg = msg;
markInvalid();
}
/*
* Check if the pending expression is ready for evaluation.
* It is complete if the next entry on the stack is a PROCESS_EXPRESSION
*/
private boolean expressionReady() {
if (nextForExpressionStackPos >= 0 && nextForExpressionStack[nextForExpressionStackPos] == PROCESS_EXPRESSION) {
checkForExpression(PROCESS_EXPRESSION); // pop it
return true;
} else
return false;
}
/*
* Push the next expression type.
*/
private void pushForExpression(int nextExpression) {
if (++nextForExpressionStackPos >= nextForExpressionStack.length) {
// Increase stack size.
int[] newStack = new int[nextForExpressionStackPos*2]; // So room to grow without excessive allocations.
System.arraycopy(nextForExpressionStack, 0, newStack, 0, nextForExpressionStack.length);
nextForExpressionStack = newStack;
}
nextForExpressionStack[nextForExpressionStackPos] = nextExpression;
}
/*
* Check if expression is complete, and if it is, process it.
*/
private void processExpression() throws ThrowableProxy, NoExpressionValueException {
while (expressionReady()) {
try {
// We've received all of the expressions for the expression, so process it.
int expType = ((Integer) pop()).intValue();
switch (expType) {
case IInternalExpressionConstants.CAST_EXPRESSION:
pushCastToProxy(pop());
break;
case IInternalExpressionConstants.INSTANCEOF_EXPRESSION:
pushInstanceofToProxy(pop());
break;
case IInternalExpressionConstants.PREFIX_EXPRESSION:
pushPrefixToProxy(((Integer)pop()).intValue());
break;
case IInternalExpressionConstants.INFIX_EXPRESSION:
pushInfixToProxy(((Integer) pop()).intValue(), ((Integer) pop()).intValue());
break;
case IInternalExpressionConstants.ARRAY_ACCESS_EXPRESSION:
pushArrayAccessToProxy(((Integer) pop()).intValue());
break;
case IInternalExpressionConstants.ARRAY_CREATION_EXPRESSION:
pushArrayCreationToProxy(pop(), ((Integer) pop()).intValue());
break;
case IInternalExpressionConstants.ARRAY_INITIALIZER_EXPRESSION:
pushArrayInitializerToProxy(pop(), ((Integer) pop()).intValue());
break;
case IInternalExpressionConstants.CLASS_INSTANCE_CREATION_EXPRESSION:
pushClassInstanceCreationToProxy(pop(), ((Integer) pop()).intValue());
break;
case IInternalExpressionConstants.FIELD_ACCESS_EXPRESSION:
pushFieldAccessToProxy((String) pop(), ((Boolean) pop()).booleanValue());
break;
case IInternalExpressionConstants.METHOD_EXPRESSION:
pushMethodInvocationToProxy((String) pop(), ((Boolean) pop()).booleanValue(), ((Integer) pop()).intValue());
break;
case IInternalExpressionConstants.CONDITIONAL_EXPRESSION:
pushConditionalToProxy(((Integer) pop()).intValue());
break;
default:
internalProcessUnknownExpressionType(expType);
}
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
}
private void internalProcessUnknownExpressionType(int expressionType) throws IllegalArgumentException {
if (!processUnknownExpressionType(expressionType))
throw new IllegalArgumentException();
}
/**
* An unknown expression type was found in the processing of expression stack. Subclasses can override
* to process new types of expressions.
* <p>
* Overrides must return <code>true</code> if they processed the expression type. If they return <code>false</code>
* it means they didn't understand it either and we should do default processing for unknow type.
* @param expressionType
* @return <code>true</code> if type was processed, <code>false</code> if not known by subclass either.
*
* @since 1.0.0
*/
protected boolean processUnknownExpressionType(int expressionType) {
return false;
}
/**
* Create the expression.
*
* @param registry
*
* @since 1.0.0
*/
protected Expression(ProxyFactoryRegistry registry) {
this.registry = registry;
this.beanProxyFactory = this.registry.getBeanProxyFactory();
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#invokeExpression()
*/
public final void invokeExpression() throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
try {
checkForExpression(IExpressionConstants.ROOTEXPRESSION); // We are at the root.
pushInvoke();
} finally {
markInvalid(); // Mark invalid so any new calls after this will fail.
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#getExpressionValue()
*/
public final IBeanProxy getExpressionValue() throws ThrowableProxy, NoExpressionValueException, IllegalStateException {
try {
checkForExpression(IExpressionConstants.ROOTEXPRESSION); // We are at the root.
return pullProxyValue(); // Get the top value.
} finally {
markInvalid(); // Mark invalid so any new calls after this will fail.
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createArrayAccess(int, int)
*/
public final void createArrayAccess(int forExpression, int indexCount) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushForExpression(PROCESS_EXPRESSION);
int i = indexCount;
while (i-- > 0)
pushForExpression(IExpressionConstants.ARRAYACCESS_INDEX);
pushForExpression(IExpressionConstants.ARRAYACCESS_ARRAY);
push(indexCount == 1 ? ARRAYACCESS_INDEX_1 : new Integer(indexCount));
push(ARRAYACCESS);
processExpression(); // See if previous expression is ready for processing.
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createArrayCreation(int, java.lang.String, int)
*/
public final void createArrayCreation(int forExpression, String type, int dimensionExpressionCount)
throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushArrayCreation(type, dimensionExpressionCount); // Push this onto the local stack to wait for completion.
processExpression(); // See if previous expression is ready for processing.
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/*
* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createArrayCreation(int, org.eclipse.jem.internal.proxy.core.IBeanTypeProxy, int)
*/
public final void createArrayCreation(int forExpression, IBeanTypeProxy type, int dimensionExpressionCount)
throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushArrayCreation(type, dimensionExpressionCount); // Push this onto the local stack to wait for completion.
processExpression(); // See if previous expression is ready for processing.
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
private void pushArrayCreation(Object type, int dimensionExpressionCount) {
switch (dimensionExpressionCount) {
case 0:
push(ARRAY_CREATION_DIMENSION_0);
break;
case 1:
push(ARRAY_CREATION_DIMENSION_1);
break;
default:
push(new Integer(dimensionExpressionCount));
break;
}
push(type);
push(ARRAYCREATION);
pushForExpression(PROCESS_EXPRESSION);
if (dimensionExpressionCount == 0)
pushForExpression(ARRAY_INITIALIZER);
else {
while(dimensionExpressionCount-- >0)
pushForExpression(IExpressionConstants.ARRAYCREATION_DIMENSION);
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createArrayInitializer(int)
*/
public final void createArrayInitializer(int expressionCount) throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
try {
// This is special, we could be waiting for an array initializer or an array initializer expression.
// We will peek to see what it is and handle it.
if (peekForExpression(ARRAY_INITIALIZER))
checkForExpression(ARRAY_INITIALIZER);
else
checkForExpression(IExpressionConstants.ARRAYINITIALIZER_EXPRESSION);
Object arrayType = peek(2); // Get the type from the value stack. Do before I mess up the stack.
switch (expressionCount) {
case 0:
push(ARRAYINITIALIZER_COUNT_0);
break;
case 1:
push(ARRAYINITIALIZER_COUNT_1);
break;
case 2:
push(ARRAYINITIALIZER_COUNT_2);
break;
default:
push(new Integer(expressionCount));
break;
}
if (arrayType instanceof String) {
// Need to remove the end set of "[]" to reduce by one dimension.
String at = (String) arrayType;
int i = at.lastIndexOf("[]"); //$NON-NLS-1$
if (i == -1)
throw new IllegalArgumentException(MessageFormat.format(ProxyMessages.getString("Expression.ArrayTypeNotAnArray_EXC_"), new Object[] {arrayType})); //$NON-NLS-1$
arrayType = at.substring(0, i);
} else if (arrayType instanceof IArrayBeanTypeProxy) {
arrayType = ((IArrayBeanTypeProxy) arrayType).getComponentType();
} else
throw new IllegalArgumentException(MessageFormat.format(ProxyMessages.getString("Expression.ArrayTypeNotAnArray_EXC_"), new Object[] {arrayType})); //$NON-NLS-1$
push(arrayType);
push(ARRAYINITIALIZER);
pushForExpression(PROCESS_EXPRESSION);
while(expressionCount-->0)
pushForExpression(IExpressionConstants.ARRAYINITIALIZER_EXPRESSION);
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createCastExpression(int, java.lang.String)
* A cast expression has one nested expression.
*/
public final void createCastExpression(int forExpression, String type) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
pushCast(forExpression, type); // Push this onto the local stack to wait for completion.
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createCastExpression(int, org.eclipse.jem.internal.proxy.core.IBeanTypeProxy)
*/
public final void createCastExpression(int forExpression, IBeanTypeProxy type) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
pushCast(forExpression, type); // Push this onto the local stack to wait for completion.
}
/*
* Push for a cast.
*/
private void pushCast(int forExpression, Object type) throws ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
push(type);
push(CAST);
pushForExpression(PROCESS_EXPRESSION);
pushForExpression(IExpressionConstants.CAST_EXPRESSION); // The next expression must be for the cast expression.
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createClassInstanceCreation(int, java.lang.String, int)
*/
public final void createClassInstanceCreation(int forExpression, String type, int argumentCount)
throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
pushClassInstanceCreation(forExpression, type, argumentCount); // Push this onto the local stack to wait for completion.
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createClassInstanceCreation(int, org.eclipse.jem.internal.proxy.core.IBeanTypeProxy, int)
*/
public final void createClassInstanceCreation(int forExpression, IBeanTypeProxy type, int argumentCount)
throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
pushClassInstanceCreation(forExpression, type, argumentCount); // Push this onto the local stack to wait for completion.
}
/*
* Push for a class instance creation
*/
private void pushClassInstanceCreation(int forExpression, Object type, int argumentCount) throws ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
switch (argumentCount) {
case 0:
push(CLASS_INSTANCE_CREATION_ARGUMENTS_0);
break;
case 1:
push(CLASS_INSTANCE_CREATION_ARGUMENTS_1);
break;
default:
push(new Integer(argumentCount));
break;
}
push(type);
push(CLASSINSTANCECREATION);
pushForExpression(PROCESS_EXPRESSION);
while(argumentCount-- >0)
pushForExpression(IExpressionConstants.CLASSINSTANCECREATION_ARGUMENT);
processExpression(); // See if previous expression is ready for processing.
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createConditionalExpression(int)
*/
public final void createConditionalExpression(int forExpression) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushForExpression(PROCESS_EXPRESSION);
pushForExpression(IExpressionConstants.CONDITIONAL_FALSE);
pushForExpression(PROCESS_EXPRESSION);
pushForExpression(IExpressionConstants.CONDITIONAL_TRUE);
pushForExpression(PROCESS_EXPRESSION);
pushForExpression(IExpressionConstants.CONDITIONAL_CONDITION);
push(CONDITIONAL_FALSEXP);
push(CONDITIONAL);
push(CONDITIONAL_TRUEEXP);
push(CONDITIONAL);
push(CONDITIONAL_TEST);
push(CONDITIONAL);
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createFieldAccess(int, java.lang.String, boolean)
*/
public final void createFieldAccess(int forExpression, String fieldName, boolean hasReceiver) throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
try {
checkForExpression(forExpression);
if (!hasReceiver)
throw new IllegalArgumentException(ProxyMessages.getString("Expression.CannotHandleNoReceiveOnFieldAccess_EXC_")); //$NON-NLS-1$
push(hasReceiver ? Boolean.TRUE : Boolean.FALSE); // We have a receiver
push(fieldName);
push(FIELDACCESS);
pushForExpression(PROCESS_EXPRESSION);
if (hasReceiver)
pushForExpression(IExpressionConstants.FIELD_RECEIVER);
processExpression(); // See if previous expression is ready for processing.
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createInfixExpression(int, int, int)
*/
public final void createInfixExpression(int forExpression, int operator, int extendedOperandCount) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
Integer inoperator = INFIX_OPERATORS[operator];
push(IN_LAST);
push(inoperator);
push(INFIX);
int i = extendedOperandCount;
while(i-->0) {
push(IN_OTHER);
push(inoperator);
push(INFIX);
}
push(IN_LEFT);
push(inoperator);
push(INFIX);
i = extendedOperandCount;
while(i-->0) {
pushForExpression(PROCESS_EXPRESSION);
pushForExpression(IExpressionConstants.INFIX_EXTENDED);
}
pushForExpression(PROCESS_EXPRESSION);
pushForExpression(IExpressionConstants.INFIX_RIGHT);
pushForExpression(PROCESS_EXPRESSION);
pushForExpression(IExpressionConstants.INFIX_LEFT);
processExpression(); // See if previous expression is ready for processing.
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createInstanceofExpression(int, java.lang.String)
*/
public final void createInstanceofExpression(int forExpression, String type) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
pushInstanceof(forExpression, type); // Push this onto the local stack to wait for completion.
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createInstanceofExpression(int, org.eclipse.jem.internal.proxy.core.IBeanTypeProxy)
*/
public final void createInstanceofExpression(int forExpression, IBeanTypeProxy type) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
pushInstanceof(forExpression, type); // Push this onto the local stack to wait for completion.
}
/*
* Push for a cast.
*/
private void pushInstanceof(int forExpression, Object type) throws ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
push(type);
push(INSTANCEOF);
pushForExpression(PROCESS_EXPRESSION);
pushForExpression(IExpressionConstants.INSTANCEOF_VALUE); // The next expression must be for the instance of expression.
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createMethodInvocation(int, java.lang.String, boolean, int)
*/
public final void createMethodInvocation(int forExpression, String name, boolean hasReceiver, int argumentCount)
throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
try {
checkForExpression(forExpression);
if (!hasReceiver)
throw new IllegalArgumentException(MessageFormat.format(ProxyMessages.getString("Expression.MethodsNeedReceiver_EXC_"), new Object[] {name})); //$NON-NLS-1$
switch (argumentCount) {
case 0 :
push(METHOD_ARGUMENTS_0);
break;
case 1 :
push(METHOD_ARGUMENTS_1);
break;
default :
push(new Integer(argumentCount));
break;
}
push(hasReceiver ? Boolean.TRUE : Boolean.FALSE);
push(name);
push(METHODINVOCATION);
pushForExpression(PROCESS_EXPRESSION);
while (argumentCount-- > 0)
pushForExpression(IExpressionConstants.METHOD_ARGUMENT);
if (hasReceiver)
pushForExpression(IExpressionConstants.METHOD_RECEIVER);
processExpression(); // See if previous expression is ready for processing.
} catch (ThrowableProxy e) {
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createPrefixExpression(int, int)
*/
public final void createPrefixExpression(int forExpression, int operator) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
push(PREFIX_OPERATORS[operator]);
push(PREFIX);
pushForExpression(PROCESS_EXPRESSION);
pushForExpression(IExpressionConstants.PREFIX_OPERAND);
processExpression(); // See if previous expression is ready for processing.
} catch (ThrowableProxy e) {
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createNull(int)
*/
public final void createNull(int forExpression) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushToProxy(null);
processExpression(); // See if previous expression is ready for processing.
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createTypeLiteral(int, java.lang.String)
*/
public final void createTypeLiteral(int forExpression, String type) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushTypeLiteralToProxy(type);
processExpression(); // See if previous expression is ready for processing.
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createTypeReceiver(java.lang.String)
*/
public final void createTypeReceiver(String type) throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
pushTypeReceiver(type);
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createTypeReceiver(org.eclipse.jem.internal.proxy.core.IBeanTypeProxy)
*/
public final void createTypeReceiver(IBeanTypeProxy type) throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
pushTypeReceiver(type);
}
/*
* Push for a type receiver.
* @param type
*
* @since 1.0.0
*/
private void pushTypeReceiver(Object type) throws ThrowableProxy, NoExpressionValueException {
try {
// This is special because type receivers are only valid as the receiver for a field access or a method access.
// Since each has a different forExpression we need to test for one or the other. It doesn't make any difference
// which one it is, but it must be one or the other.
if (peekForExpression(FIELD_RECEIVER))
checkForExpression(FIELD_RECEIVER);
else
checkForExpression(METHOD_RECEIVER);
pushTypeReceiverToProxy(type);
processExpression(); // See if previous expression is ready for processing.
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/*
* For all of the primitive types we will be creating a IBeanProxy for them. That is because that
* would be the expected result of the expression, and no need to get the other side involved.
*/
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, boolean)
*/
public final void createPrimitiveLiteral(int forExpression, boolean value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushToProxy(beanProxyFactory.createBeanProxyWith(value));
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, char)
*/
public final void createPrimitiveLiteral(int forExpression, char value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushToProxy(beanProxyFactory.createBeanProxyWith(value));
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, byte)
*/
public final void createPrimitiveLiteral(int forExpression, byte value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushToProxy(beanProxyFactory.createBeanProxyWith(value));
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, double)
*/
public final void createPrimitiveLiteral(int forExpression, double value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushToProxy(beanProxyFactory.createBeanProxyWith(value));
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, float)
*/
public final void createPrimitiveLiteral(int forExpression, float value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushToProxy(beanProxyFactory.createBeanProxyWith(value));
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, int)
*/
public final void createPrimitiveLiteral(int forExpression, int value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushToProxy(beanProxyFactory.createBeanProxyWith(value));
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, long)
*/
public final void createPrimitiveLiteral(int forExpression, long value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushToProxy(beanProxyFactory.createBeanProxyWith(value));
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, short)
*/
public final void createPrimitiveLiteral(int forExpression, short value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushToProxy(beanProxyFactory.createBeanProxyWith(value));
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createStringLiteral(int, java.lang.String)
*/
public final void createStringLiteral(int forExpression, String value) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushToProxy(beanProxyFactory.createBeanProxyWith(value));
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.proxy.core.IExpression#createProxyExpression(int, org.eclipse.jem.internal.proxy.core.IBeanProxy)
*/
public final void createProxyExpression(int forExpression, IBeanProxy proxy) throws IllegalStateException, ThrowableProxy, NoExpressionValueException {
try {
checkForExpression(forExpression);
pushToProxy(proxy);
processExpression();
} catch (ThrowableProxy e) {
markInvalid();
throw e;
} catch (NoExpressionValueException e) {
markInvalid();
throw e;
} catch (RuntimeException e) {
markInvalid();
throw e;
}
}
/**
* Push this proxy to the other side. It will simply take the proxy and push it onto
* its evaluation stack. It will be treated as the result of an expression. It's just
* that the expression was evaluatable on this side (since it is already a proxy).
*
* @param proxy
* @throws ThrowableProxy
*
* @since 1.0.0
*/
protected abstract void pushToProxy(IBeanProxy proxy) throws ThrowableProxy;
/**
* Tell the other side we are complete. This is only called for invoked expressions,
* i.e. no return value.
*
* @throws ThrowableProxy
*
* @since 1.0.0
*/
protected abstract void closeProxy();
/**
* Do invoke. This should simply make sure everything is done and throw any pending errors.
*
* @throws ThrowableProxy
*
* @since 1.0.0
*/
protected abstract void pushInvoke() throws ThrowableProxy, NoExpressionValueException;
/**
* Pull the top expression value from the evaluation stack. It will also under
* the covers call closeProxy.
*
* @return The top level evaluation stack value.
* @throws ThrowableProxy
* @throws NoExpressionValueException
*
* @since 1.0.0
*/
protected abstract IBeanProxy pullProxyValue() throws ThrowableProxy, NoExpressionValueException;
/**
* Push to proxy the cast expression. The expression to use will be on the top of its evaluation stack.
* The result of the cast expression will be placed onto the evaluation stack.
*
* @param type Cast type. It may be either <code>String</code> (the value is the type to be searched for) or <code>IBeanTypeProxy</code> (it is of that type that the proxy is wrappering).
* @throws ThrowableProxy
* @throws NoExpressionValueException
*
* @since 1.0.0
*/
protected abstract void pushCastToProxy(Object type) throws ThrowableProxy, NoExpressionValueException;
/**
* Push to proxy the instanceof expression. The expression to use will be on the top of its evaluation stack.
* The result of the instanceof expression will be placed onto the evaluation stack.
*
* @param type Instanceof type. It may be either <code>String</code> (the value is the type to be searched for) or <code>IBeanTypeProxy</code> (it is of that type that the proxy is wrappering).
* @throws ThrowableProxy
* @throws NoExpressionValueException
*
* @since 1.0.0
*/
protected abstract void pushInstanceofToProxy(Object type) throws ThrowableProxy, NoExpressionValueException;
/**
* Push to proxy the infix operation. This is called on the completion of each operand of the expression.
* So it will be called a minimum of two times.
*
* @param operator The operator, the values are from IExpressionConstants infix operators.
* @param operandType The operand type. left, other, or last. The values are from the IInternalExpressionConstants infix operations.
* @throws ThrowableProxy
* @throws NoExpressionValueException
*
* @see IExpressionConstants#IN_AND
* @see IInternalExpressionConstants#INFIX_LAST_OPERAND
* @since 1.0.0
*/
protected abstract void pushInfixToProxy(int operator, int operandType) throws ThrowableProxy, NoExpressionValueException;
/**
* Push to proxy the prefix expression. The expression to use will be on top of its evaluation stack.
* The result of the prefix operation will be placed onto the evaluation stack.
*
* @param operator The operator, the values are from IExpressionConstants prefix operators.
* @throws ThrowableProxy
* @throws NoExpressionValueException
*
* @see IExpressionConstants#PRE_MINUS
* @since 1.0.0
*/
protected abstract void pushPrefixToProxy(int operator) throws ThrowableProxy, NoExpressionValueException;
/**
* Push to proxy the type literal string. The result of the type literal string will be placed onto the evaluation
* stack.
*
* @param type
* @throws ThrowableProxy
*
* @since 1.0.0
*/
protected abstract void pushTypeLiteralToProxy(String type) throws ThrowableProxy;
/**
* Push to proxy the array access. The result will be placed onto the evaluation stack.
*
* @param indexCount
* @throws ThrowableProxy
* @throws NoExpressionValueException
*
* @since 1.0.0
*/
protected abstract void pushArrayAccessToProxy(int indexCount) throws ThrowableProxy, NoExpressionValueException;
/**
* Push to proxy the array creation. The result will be placed onto the evaluation stack.
* @param type The array type. (must be an array type) It may be either <code>String</code> (the value is the type to be searched for) or <code>IBeanTypeProxy</code> (it is of that type that the proxy is wrappering).
* @param dimensionCount
* @throws ThrowableProxy
* @throws NoExpressionValueException
*
* @since 1.0.0
*/
protected abstract void pushArrayCreationToProxy(Object type, int dimensionCount) throws ThrowableProxy, NoExpressionValueException;
/**
* Push to proxy the array initializer. The resulting array will be placed onto the evaluation stack.
* @param type The array type minus one dimension. (must be an array type) It may be either <code>String</code> (the value is the type to be searched for) or <code>IBeanTypeProxy</code> (it is of that type that the proxy is wrappering).
* @param expressionCount
* @throws ThrowableProxy
* @throws NoExpressionValueException
*
* @since 1.0.0
*/
protected abstract void pushArrayInitializerToProxy(Object type, int expressionCount) throws ThrowableProxy, NoExpressionValueException;
/**
* Push to proxy the class instance creation. The resulting class instance will be placed onto the evaluation stack.
*
* @param type Class type. It may be either <code>String</code> (the value is the type to be searched for) or <code>IBeanTypeProxy</code> (it is of that type that the proxy is wrappering).
* @param argumentCount The number of arguments.
* @throws ThrowableProxy
* @throws NoExpressionValueException
*
* @since 1.0.0
*/
protected abstract void pushClassInstanceCreationToProxy(Object type, int argumentCount) throws ThrowableProxy, NoExpressionValueException;
/**
* Push to proxy the type receiver. The resulting class will be placed onto the evaluation stack, along with it also
* being the expression type.
* @param type Class type. It may be either <code>String</code> (the value is the type to be searched for) or <code>IBeanTypeProxy</code> (it is of that type that the proxy is wrappering).
* @throws ThrowableProxy
*
* @since 1.0.0
*/
protected abstract void pushTypeReceiverToProxy(Object type) throws ThrowableProxy;
/**
* Push to proxy the field access. The result value will be placed onto the evaluation stack.
* @param fieldName The name of the field.
* @param hasReceiver Has receiver flag.
* @throws ThrowableProxy
* @throws NoExpressionValueException
*
* @since 1.0.0
*/
protected abstract void pushFieldAccessToProxy(String fieldName, boolean hasReceiver) throws ThrowableProxy, NoExpressionValueException;
/**
* Push to proxy the method invocation. The result value will be placed onto the evaluation stack.
*
* @param methodName
* @param hasReceiver
* @param argCount
* @throws ThrowableProxy
* @throws NoExpressionValueException
*
* @since 1.0.0
*/
protected abstract void pushMethodInvocationToProxy(String methodName, boolean hasReceiver, int argCount) throws ThrowableProxy, NoExpressionValueException;
/**
* Push to proxy the conditional expression. This will be called on each part of expression. The expression type
* will be the current part (e.g. test, true, false).
*
* @param expressionType The expression type, one of IExpressionConstants.CONDITIONAL_* constants.
* @throws ThrowableProxy
* @throws NoExpressionValueException
*
* @see IExpressionConstants#CONDITIONAL_CONDITION
* @since 1.0.0
*/
protected abstract void pushConditionalToProxy(int expressionType) throws ThrowableProxy, NoExpressionValueException;
}