| /******************************************************************************* |
| * 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; |
| } |