Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/Expression.java')
-rw-r--r--plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/Expression.java2546
1 files changed, 0 insertions, 2546 deletions
diff --git a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/Expression.java b/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/Expression.java
deleted file mode 100644
index 2ab151187..000000000
--- a/plugins/org.eclipse.jem.proxy/proxy/org/eclipse/jem/internal/proxy/core/Expression.java
+++ /dev/null
@@ -1,2546 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2005 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.15 $ $Date: 2005/11/11 15:49:30 $
- */
-package org.eclipse.jem.internal.proxy.core;
-
-import java.text.MessageFormat;
-import java.util.*;
-
-import org.eclipse.jem.internal.proxy.initParser.tree.*;
-
-/**
- * This is implementation of IExpression. 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. All registry specific implementations of IExpression must subclass this class.
- * <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 for subclasses 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 reason.
- * <p>
- * This class is not thread-safe.
- * <p>
- * This class also has API of its own and can be used by customers for advanced usage. Those advanced API are
- * listed on each method as to whether it is customer API or implementers API (i.e. API for implementers of
- * expression subclasses to use).
- *
- *
- * @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;
- protected Boolean traceFlag;
-
- /**
- * Answer whether trace has been explicitly set.
- * This is not in the IExpression interface because it is for advanced users.
- * @return
- *
- * @since 1.1.0
- */
- public boolean isTraceSet() {
- return traceFlag != null;
- }
-
- /**
- * Answer if trace is on. If not explicitly set this will answer false.
- * Use {@link Expression#isTraceSet()} first to determine if this
- * should be called or not.
- * This is not in the IExpression interface because it is for advanced users.
- * @return
- *
- * @since 1.1.0
- */
- public boolean isTrace() {
- return traceFlag != null ? traceFlag.booleanValue() : false;
- }
-
- /**
- * Explicitly set the trace flag. This will only be honoured before any
- * expressions have been created. After that this will be ignored.
- * The trace is initially set to use default. Once set it cannot be unset.
- * This is not in the IExpression interface because it is for advanced users.
- * @param trace
- *
- * @since 1.1.0
- */
- public void setTrace(boolean trace) {
- traceFlag = Boolean.valueOf(trace);
- }
-
- /**
- * 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_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 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 ForExpression ARRAY_INITIALIZER = new ExpressionEnum(Integer.MIN_VALUE+1, "Array Initializer Internal"); //$NON-NLS-1$
-
- /*
- * 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_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).
- */
-
- /*
- * 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 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
- *
- */
-
- /*
- * 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)
- */
-
- /*
- * 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)
- */
-
- /*
- * 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).
- */
-
- /*
- * 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)
- */
-
- /*
- * 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 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.
-
-
- /*
- * Assignment expression
- * The expression stack will have:
- * IExpression.ASSIGNMENT_RIGHT
- * IExpression.ASSIGNMENT_LEFT
- * PROCESS_EXPRESSION
- *
- * The value stack will have:
- * ASSIGNMENT
- * left expression (variable reference)
- * right expression
- */
-
- /*
- * Assignment proxy expression
- * The expression stack will have:
- * IExpression.ASSIGNMENT_RIGHT
- * PROCESS_EXPRESSION
- *
- * The value stack will have:
- * ASSIGNMENT_PROXY
- * expression proxy (an expression proxy)
- */
-
- /*
- * 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 ForExpression[] nextForExpressionStack = new ForExpression[30];
- private int nextForExpressionStackPos = -1; // Position of top entry in stack.
- private boolean expressionValid = true; // Is the expression currently valid.
- private String invalidMsg = null; // Msg for being invalid if default msg not sufficient.
- private List expressionProxies; // List of expression proxies. The index of the proxy is its id. This list must never shrink in size.
-
- // A MarkEntry. To allow restore in case of error.
- private static class MarkEntry {
- public int markID;
- public int controlStackPos; // Position of control stack at time of mark.
- public int nextExpressionStackPos; // Position of nextForExpression stack at time of mark.
- public int expressionProxiesPos; // Position of expressionProxies list at time of mark.
- }
-
- private int highestMarkID = 0; // Next mark id. '0' is invalid, as in no marks. This is incremented for each new mark. Never decremented.
- private MarkEntry currentMarkEntry; // Just a convienence to the current mark entry so no need to look into the list every time.
- private List markEntries; // Stack of mark entries.
-
- // This class is here so we can add our special internal ForExpression: PROCESS_EXPRESSION. These are never used outside Expression.
- private static class ExpressionEnum extends ForExpression {
-
- public ExpressionEnum(int value, String name) {
- super(value, name);
- }
-
- }
-
- // This is pushed onto the next expression stack, and when it is popped, then the expression is complete and ready to be pushed to the proxy side.
- private static final ForExpression PROCESS_EXPRESSION = new ExpressionEnum(Integer.MIN_VALUE, "Process Expression"); //$NON-NLS-1$
-
- // This is pushed onto the next expression stack for end block and will test if this there to make sure that it is being called correctly.
- private static final ForExpression BLOCKEND_EXPRESSION = new ExpressionEnum(PROCESS_EXPRESSION.getValue()-2, "End Block Expression"); //$NON-NLS-1$
-
- // This is pushed onto the next expression stack for end try and will test if this there to make sure that it is being called correctly.
- private static final ForExpression TRYEND_EXPRESSION = new ExpressionEnum(BLOCKEND_EXPRESSION.getValue()-1, "End Try Expression"); //$NON-NLS-1$
-
- // This is pushed onto the next expression stack for catch and will test if this there to make sure that it is being called correctly.
- private static final ForExpression TRYCATCH_EXPRESSION = new ExpressionEnum(TRYEND_EXPRESSION.getValue()-1, "Catch Expression"); //$NON-NLS-1$
-
-
- // This is pushed onto the next expression stack for begin thread transfer and will test if this there to make sure that it is being called correctly.
- private static final ForExpression THREADTRANSFER_EXPRESSION = new ExpressionEnum(TRYCATCH_EXPRESSION.getValue()-1, "Catch Expression"); //$NON-NLS-1$
-
- // This is pushed onto the next expression stack for end subexpression and will test if this there to make sure that it is being called correctly.
- private static final ForExpression SUBEXPRESSIONEND_EXPRESSION = new ExpressionEnum(THREADTRANSFER_EXPRESSION.getValue()-2, "End Subexpression"); //$NON-NLS-1$
-
- /**
- * Check the for expression, and if legal, set to the next valid for expression type,
- * if it can. If the stack entry is ROOTEXPRESSION, and the forExpression is ROOTEXPRESSION,
- * then the expression is allowed, but it is not popped. It must be popped later when appropriate.
- * <p>
- * This is for "block" expressions. We don't want to pop down the stack passed the ROOTEXPRESSION
- * that got added by the create block until we get an end block. That allows root expressions to
- * be added to the block without the stack popping up past the block start in the stack.
- *
- * @param forExpression
- * @throws IllegalStateException
- *
- * @since 1.0.0
- */
- protected final void checkForExpression(ForExpression forExpression) throws IllegalStateException {
- if (expressionValid) {
- if (nextForExpressionStackPos == -1)
- if (forExpression == ForExpression.ROOTEXPRESSION)
- return; // valid. We are at the root (i.e. nothing is waiting).
- else
- ; // invalid. drop through
- else if (nextForExpressionStack[nextForExpressionStackPos] == forExpression) {
- // Valid, either the root expression matched (We don't implicitly pop those. That needs to be done explicitly).
- // Or we matched non-root, those will be popped.
- if (forExpression != ForExpression.ROOTEXPRESSION) {
- popForExpression(); // Pop the stack since stack not a root expression.
- }
- return;
- }
- } else {
- String expMsg = invalidMsg != null ? MessageFormat.format(ProxyMessages.Expression_InInvalidStateDueTo_EXC_, new Object[] {invalidMsg}) : ProxyMessages.Expression_InInvalidState_EXC_;
- throw new IllegalStateException(expMsg);
- }
-
- // If we got here, then invalid.
- ForExpression expected = nextForExpressionStackPos >= 0 ? nextForExpressionStack[nextForExpressionStackPos] : ForExpression.ROOTEXPRESSION;
- expressionValid = false;
- throw new IllegalStateException(MessageFormat.format(ProxyMessages.Expression_TypeSentInInvalidOrder_EXC_, new Object[] {forExpression, expected}));
- }
-
- /**
- * Pop the top for expression, whatever it is.
- * @throws IllegalStateException thrown if try to pop through through the current mark entry. The endMark is the only one who can do this.
- * @since 1.1.0
- */
- protected final void popForExpression() throws IllegalStateException {
- if (expressionValid && nextForExpressionStackPos >= 0) {
- nextForExpressionStackPos--;
- if (currentMarkEntry != null && nextForExpressionStackPos < currentMarkEntry.nextExpressionStackPos) {
- nextForExpressionStackPos++; // Restore to what it was
- throwInvalidMarkNesting();
- }
- }
- }
-
- /*
- * @throws IllegalStateException
- *
- * @since 1.1.0
- */
- private void throwInvalidMarkNesting() throws IllegalStateException {
- expressionValid = false;
- throw new IllegalStateException(MessageFormat.format(ProxyMessages.Expression_InvalidMarkNesting, new Object[] {new Integer(currentMarkEntry != null ? currentMarkEntry.markID : 0)}));
- }
-
- /**
- * 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(ForExpression forExpression) {
- if (expressionValid) {
- if (nextForExpressionStackPos == -1)
- if (forExpression == ForExpression.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() {
- expressionValid = false;
- }
-
- /**
- * 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();
- }
-
- public void close() {
- nextForExpressionStackPos = -1;
- controlStack.clear();
- if (expressionProxies != null)
- markAllProxiesNotResolved(expressionProxies); // They weren't processed, close must of been called early.
- expressionProxies = null;
- markEntries = null;
- expressionValid = false;
- closeProxy();
- }
-
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#isValid()
- */
- public boolean isValid() {
- return expressionValid;
- }
-
- /*
- * 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(ForExpression nextExpression) {
- if (++nextForExpressionStackPos >= nextForExpressionStack.length) {
- // Increase stack size.
- ForExpression[] newStack = new ForExpression[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() {
- while (expressionReady()) {
- try {
- // We've received all of the expressions for the expression, so process it.
- int expType = ((InternalExpressionTypes) pop()).getValue();
- switch (expType) {
- case InternalExpressionTypes.CAST_EXPRESSION_VALUE:
- pushCastToProxy((IProxyBeanType) pop());
- break;
- case InternalExpressionTypes.INSTANCEOF_EXPRESSION_VALUE:
- pushInstanceofToProxy((IProxyBeanType) pop());
- break;
- case InternalExpressionTypes.PREFIX_EXPRESSION_VALUE:
- pushPrefixToProxy((PrefixOperator)pop());
- break;
- case InternalExpressionTypes.INFIX_EXPRESSION_VALUE:
- pushInfixToProxy((InfixOperator) pop(), (InternalInfixOperandType) pop());
- break;
- case InternalExpressionTypes.ARRAY_ACCESS_EXPRESSION_VALUE:
- pushArrayAccessToProxy(((Integer) pop()).intValue());
- break;
- case InternalExpressionTypes.ARRAY_CREATION_EXPRESSION_VALUE:
- pushArrayCreationToProxy((IProxyBeanType) pop(), ((Integer) pop()).intValue());
- break;
- case InternalExpressionTypes.ARRAY_INITIALIZER_EXPRESSION_VALUE:
- pushArrayInitializerToProxy((IProxyBeanType) pop(), ((Integer) pop()).intValue(), ((Integer) pop()).intValue());
- break;
- case InternalExpressionTypes.CLASS_INSTANCE_CREATION_EXPRESSION_VALUE:
- pushClassInstanceCreationToProxy((IProxyBeanType) pop(), ((Integer) pop()).intValue());
- break;
- case InternalExpressionTypes.FIELD_ACCESS_EXPRESSION_VALUE:
- pushFieldAccessToProxy(pop(), ((Boolean) pop()).booleanValue());
- break;
- case InternalExpressionTypes.METHOD_EXPRESSION_VALUE:
- pushMethodInvocationToProxy(pop(), ((Boolean) pop()).booleanValue(), ((Integer) pop()).intValue());
- break;
- case InternalExpressionTypes.CONDITIONAL_EXPRESSION_VALUE:
- pushConditionalToProxy((InternalConditionalOperandType) pop());
- break;
- case InternalExpressionTypes.ASSIGNMENT_PROXY_EXPRESSION_VALUE:
- pushAssignmentToProxy((ExpressionProxy) pop());
- break;
- case InternalExpressionTypes.ASSIGNMENT_EXPRESSION_VALUE:
- pushAssignmentToProxy();
- break;
- case InternalExpressionTypes.BLOCK_END_EXPRESSION_VALUE:
- pushBlockEndToProxy(((Integer) pop()).intValue());
- break;
- case InternalExpressionTypes.TRY_END_EXPRESSION_VALUE:
- pushTryEndToProxy(((Integer) pop()).intValue());
- break;
- case InternalExpressionTypes.THROW_EXPRESSION_VALUE:
- pushThrowToProxy();
- break;
- case InternalExpressionTypes.IF_TEST_EXPRESSION_VALUE:
- pushIfTestToProxy();
- break;
- case InternalExpressionTypes.IF_ELSE_EXPRESSION_VALUE:
- pushIfElseToProxy((InternalIfElseOperandType) pop());
- break;
- case InternalExpressionTypes.SUBEXPRESSION_END_EXPRESSION_VALUE:
- pushSubexpressionEndToProxy(((Integer) pop()).intValue());
- break;
- default:
- internalProcessUnknownExpressionType(expType);
- break;
- }
- } 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#getRegistry()
- */
- public ProxyFactoryRegistry getRegistry() {
- return registry;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#invokeExpression()
- */
- public final void invokeExpression() throws ThrowableProxy, IllegalStateException, NoExpressionValueException {
- try {
- checkForExpression(ForExpression.ROOTEXPRESSION); // We are at the root.
- popForExpression(); // Get rid of any intermediate roots.
- checkForExpression(ForExpression.ROOTEXPRESSION); // We should be at true root now. We don't have more than one intermediate root pushed in sequence.
- List proxies = expressionProxies;
- expressionProxies = null;
- pushInvoke(processExpressionProxyCallbacks(proxies), proxies);
- } finally {
- markInvalid(); // Mark invalid so any new calls after this will fail.
- close();
- }
- }
-
- /*
- * Process the expression proxy callbacks, if any.
- * @return the number of proxies that have callbacks.
- */
- private int processExpressionProxyCallbacks(List proxies) {
- if (proxies != null) {
- // Strip list down to only those with callbacks and send on.
- int proxiesWithCallbacks = 0;
- for (ListIterator eps = proxies.listIterator(); eps.hasNext();) {
- ExpressionProxy proxy = (ExpressionProxy) eps.next();
- if (!proxy.hasListeners())
- eps.set(null); // Remove it from the list. No one cares.
- else
- proxiesWithCallbacks++;
- }
- return proxiesWithCallbacks;
- }
- return 0;
- }
-
- /**
- * Called to validate this is a valid proxy for this expression. This could happen
- * if a proxy from another expression is sent to this expression. If the proxy
- * is a bean proxy or is an expression proxy for this expression, then this
- * just returns. Else it will throw the {@link IllegalArgumentException}.
- * @param proxy
- * @throws IllegalArgumentException if the proxy is an expression proxy for another expression.
- *
- * @since 1.1.0.1
- */
- private void validateProxy(IProxy proxy) throws IllegalArgumentException {
- if (proxy != null && (proxy.isExpressionProxy() && ((ExpressionProxy) proxy).getExpression() != this))
- throw new IllegalArgumentException(ProxyMessages.Expression_InvalidProxy);
- }
-
- /**
- * Called by subclass to fill in the value of an expression proxy. See {@link Expression#pullProxyValue(int, List))} for an example of who would call it.
- * @param ep
- * @param beanproxy
- *
- * @since 1.1.0
- */
- protected void fireProxyResolved(ExpressionProxy ep, IBeanProxy beanproxy) {
- ep.fireResolved(beanproxy);
- }
-
- /**
- * Called by subclass to fire proxy was not resolved. See {@link Expression#pullProxyValue(int, List))} for an example of who would call it.
- * @param ep
- *
- * @since 1.1.0
- */
- protected void fireProxyNotResolved(ExpressionProxy ep) {
- ep.fireNotResolved();
- }
-
- /**
- * Called by subclass to fire proxy resolved to a void return type. See {@link Expression#pullProxyValue(int, List))} for an example of who would call it.
- * @param ep
- *
- * @since 1.1.0
- */
- protected void fireProxyVoid(ExpressionProxy ep) {
- ep.fireVoidResolved();
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#getExpressionValue()
- */
- public final IBeanProxy getExpressionValue() throws ThrowableProxy, NoExpressionValueException, IllegalStateException {
- try {
- checkForExpression(ForExpression.ROOTEXPRESSION); // We are at the root.
- popForExpression(); // Get rid of any intermediate roots.
- checkForExpression(ForExpression.ROOTEXPRESSION); // We should be at true root now. We don't have more than one intermediate root pushed in sequence.
- List proxies = expressionProxies;
- expressionProxies = null;
- return pullProxyValue(processExpressionProxyCallbacks(proxies), proxies); // Get the top value.
- } finally {
- markInvalid(); // Mark invalid so any new calls after this will fail.
- close();
- }
- }
-
-
- /**
- * Mark the list of proxies as not resolved.
- *
- * @since 1.1.0
- */
- protected void markAllProxiesNotResolved(List proxies) {
- if (proxies != null) {
- for (ListIterator eps = proxies.listIterator(); eps.hasNext();) {
- ExpressionProxy proxy = (ExpressionProxy) eps.next();
- if (proxy != null && proxy.hasListeners())
- fireProxyNotResolved(proxy);
- }
- }
- }
-
- private int blockNumber = -1; // Current block number. This is always incrementing.
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createBlockBegin()
- */
- public final int createBlockBegin() throws IllegalStateException {
- try {
- // Blocks are special, they can be anywhere at root, of could be the true or else clause of an if/else.
- if (peekForExpression(ForExpression.ROOTEXPRESSION))
- checkForExpression(ForExpression.ROOTEXPRESSION);
- else if (peekForExpression(ForExpression.IF_TRUE))
- checkForExpression(ForExpression.IF_TRUE);
- else
- checkForExpression(ForExpression.IF_ELSE);
-
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(BLOCKEND_EXPRESSION);
- pushForExpression(ForExpression.ROOTEXPRESSION);
-
- pushBlockBeginToProxy(++blockNumber);
- push(new Integer(blockNumber));
- push(InternalExpressionTypes.BLOCK_END_EXPRESSION);
- processExpression();
- return blockNumber;
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createBlockBreak(int)
- */
- public final void createBlockBreak(int blockNumber) throws IllegalStateException {
- try {
- checkForExpression(ForExpression.ROOTEXPRESSION);
- pushBlockBreakToProxy(blockNumber);
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createBlockEnd()
- */
- public final void createBlockEnd() throws IllegalStateException {
- try {
- checkForExpression(ForExpression.ROOTEXPRESSION);
- popForExpression(); // Remove the root expression since block is done.
- checkForExpression(BLOCKEND_EXPRESSION); // This needs to be next for it to be valid.
- processExpression(); // Now let it handle the previously pushed end block, containing the block number being ended.
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createArrayAccess(int, int)
- */
- public final void createArrayAccess(ForExpression forExpression, int indexCount) {
- try {
- checkForExpression(forExpression);
- pushForExpression(PROCESS_EXPRESSION);
- int i = indexCount;
- while (i-- > 0)
- pushForExpression(ForExpression.ARRAYACCESS_INDEX);
- pushForExpression(ForExpression.ARRAYACCESS_ARRAY);
-
- push(indexCount == 1 ? ARRAYACCESS_INDEX_1 : new Integer(indexCount));
- push(InternalExpressionTypes.ARRAY_ACCESS_EXPRESSION);
- processExpression(); // See if previous expression is ready for processing.
- } 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(ForExpression forExpression, String type, int dimensionExpressionCount)
- throws IllegalStateException {
- pushArrayCreation(forExpression, getProxyBeanType(type), dimensionExpressionCount);
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createArrayCreation(org.eclipse.jem.internal.proxy.initParser.tree.ForExpression, org.eclipse.jem.internal.proxy.core.IProxyBeanType, int)
- */
- public final void createArrayCreation(ForExpression forExpression, IProxyBeanType type, int dimensionExpressionCount)
- throws IllegalStateException, IllegalArgumentException {
- pushArrayCreation(forExpression, type, dimensionExpressionCount);
- }
-
- private void pushArrayCreation(ForExpression forExpression, IProxyBeanType type, int dimensionExpressionCount) throws IllegalStateException, IllegalArgumentException {
- try {
- checkForExpression(forExpression);
- validateProxy(type);
- 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(InternalExpressionTypes.ARRAY_CREATION_EXPRESSION);
-
- pushForExpression(PROCESS_EXPRESSION);
- if (dimensionExpressionCount == 0)
- pushForExpression(ARRAY_INITIALIZER);
- else {
- while (dimensionExpressionCount-- > 0)
- pushForExpression(ForExpression.ARRAYCREATION_DIMENSION);
- }
- processExpression(); // See if previous expression is ready for processing.
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createArrayInitializer(int)
- */
- public final void createArrayInitializer(int expressionCount) throws IllegalStateException {
- 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(ForExpression.ARRAYINITIALIZER_EXPRESSION);
-
- // At this point in time that stack may either have:
- // array_type, array_creation
- // strip_count, array_type, array_initializer
- // So we can get the array type from peek(2), and get the command type from peek(1).
- // Then if the command type is array_creation, strip_count will be inited to 0, while
- // else it will be inited to peek(3). From that we can increment the strip_count to
- // use for this initializer.
- //
- // We need to peek here because we will be adding various pushes to the stack and we
- // need to get the info while it is still at the top of the stack.
- Object arrayType = peek(2);
- int stripCount = 0;
- if (peek(1) == InternalExpressionTypes.ARRAY_INITIALIZER_EXPRESSION)
- stripCount = ((Integer) peek(3)).intValue();
-
- 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) {
- String at = (String) arrayType;
- int i = at.lastIndexOf("[]"); //$NON-NLS-1$
- if (i == -1)
- throw new IllegalArgumentException(MessageFormat.format(
- ProxyMessages.Expression_ArrayTypeNotAnArray_EXC_, new Object[] { arrayType}));
- arrayType = getProxyBeanType(at);
- } else if (!(arrayType instanceof IProxyBeanType)) {
- throw new IllegalArgumentException(MessageFormat.format(
- ProxyMessages.Expression_ArrayTypeNotAnArray_EXC_, new Object[] { arrayType}));
- }
- push(new Integer(++stripCount));
- push(arrayType);
- push(InternalExpressionTypes.ARRAY_INITIALIZER_EXPRESSION);
-
- pushForExpression(PROCESS_EXPRESSION);
- while (expressionCount-- > 0)
- pushForExpression(ForExpression.ARRAYINITIALIZER_EXPRESSION);
-
- processExpression();
- } 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(ForExpression forExpression, String type) throws IllegalStateException {
- pushCast(forExpression, getProxyBeanType(type)); // Push this onto the local stack to wait for completion.
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createCastExpression(org.eclipse.jem.internal.proxy.initParser.tree.ForExpression, org.eclipse.jem.internal.proxy.core.IProxyBeanType)
- */
- public final void createCastExpression(ForExpression forExpression, IProxyBeanType type) throws IllegalStateException, IllegalArgumentException {
- pushCast(forExpression, type); // Push this onto the local stack to wait for completion.
- }
-
- /*
- * Push for a cast.
- */
- private void pushCast(ForExpression forExpression, IProxyBeanType type) throws IllegalStateException, IllegalArgumentException {
- try {
- checkForExpression(forExpression);
- validateProxy(type);
- push(type);
- push(InternalExpressionTypes.CAST_EXPRESSION);
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.CAST_EXPRESSION); // The next expression must be for the cast expression.
- processExpression();
- } 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(ForExpression forExpression, String type, int argumentCount)
- throws IllegalStateException {
- pushClassInstanceCreation(forExpression, getProxyBeanType(type), argumentCount); // Push this onto the local stack to wait for completion.
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createClassInstanceCreation(org.eclipse.jem.internal.proxy.initParser.tree.ForExpression, org.eclipse.jem.internal.proxy.core.IProxyBeanType, int)
- */
- public final void createClassInstanceCreation(ForExpression forExpression, IProxyBeanType type, int argumentCount)
- throws IllegalStateException, IllegalArgumentException {
- pushClassInstanceCreation(forExpression, type, argumentCount); // Push this onto the local stack to wait for completion.
- }
-
- /*
- * Push for a class instance creation
- */
- private void pushClassInstanceCreation(ForExpression forExpression, IProxyBeanType type, int argumentCount) throws IllegalStateException, IllegalArgumentException {
- try {
- checkForExpression(forExpression);
- validateProxy(type);
- 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(InternalExpressionTypes.CLASS_INSTANCE_CREATION_EXPRESSION);
-
- pushForExpression(PROCESS_EXPRESSION);
- while (argumentCount-- > 0)
- pushForExpression(ForExpression.CLASSINSTANCECREATION_ARGUMENT);
- processExpression(); // See if previous expression is ready for processing.
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createConditionalExpression(int)
- */
- public final void createConditionalExpression(ForExpression forExpression) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.CONDITIONAL_FALSE);
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.CONDITIONAL_TRUE);
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.CONDITIONAL_CONDITION);
-
- push(InternalConditionalOperandType.CONDITIONAL_FALSE);
- push(InternalExpressionTypes.CONDITIONAL_EXPRESSION);
- push(InternalConditionalOperandType.CONDITIONAL_TRUE);
- push(InternalExpressionTypes.CONDITIONAL_EXPRESSION);
- push(InternalConditionalOperandType.CONDITIONAL_TEST);
- push(InternalExpressionTypes.CONDITIONAL_EXPRESSION);
- processExpression();
- } 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(ForExpression forExpression, String fieldName, boolean hasReceiver) throws IllegalStateException, IllegalArgumentException {
- try {
- // Only for string fieldnames is this invalid when no receiver because no way to determine receiver. (Don't handle implicit "this" yet for fields).
- // For the accessor that takes a IFieldProxy we can get away with no receiver because the field proxy can determine if static or not, and if not
- // static it will fail at evaluation time.
- if (!hasReceiver)
- throw new IllegalArgumentException(MessageFormat.format(
- ProxyMessages.Expression_CannotHandleNoReceiveOnFieldAccess_EXC_, new Object[] { fieldName}));
- pushFieldAccess(forExpression, fieldName, hasReceiver);
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createIfElse(boolean)
- */
- public final void createIfElse(boolean hasElseClause) throws IllegalStateException {
- try {
- checkForExpression(ForExpression.ROOTEXPRESSION);
-
- pushForExpression(PROCESS_EXPRESSION);
- if (hasElseClause) {
- pushForExpression(ForExpression.IF_ELSE);
- }
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.IF_TRUE);
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.IF_CONDITION);
-
- // We still push an else clause so that we know when finished. We don't have a pushForExpression for it because there
- // won't be any. But the else clause processing will be on the push stack so that we can clean up when end of if stmt occurs.
- push(InternalIfElseOperandType.ELSE_CLAUSE);
- push(InternalExpressionTypes.IF_ELSE_EXPRESSION);
-
- push(InternalIfElseOperandType.TRUE_CLAUSE);
- push(InternalExpressionTypes.IF_ELSE_EXPRESSION);
- push(InternalExpressionTypes.IF_TEST_EXPRESSION);
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /*
- * Push the field access.
- * @param forExpression
- * @param field String if field name, or IProxyField.
- * @param hasReceiver
- * @throws IllegalAccessException
- *
- * @since 1.1.0
- */
- private void pushFieldAccess(ForExpression forExpression, Object field, boolean hasReceiver) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- push(hasReceiver ? Boolean.TRUE : Boolean.FALSE); // We have a receiver
- push(field);
- push(InternalExpressionTypes.FIELD_ACCESS_EXPRESSION);
-
- pushForExpression(PROCESS_EXPRESSION);
- if (hasReceiver)
- pushForExpression(ForExpression.FIELD_RECEIVER);
- processExpression(); // See if previous expression is ready for processing.
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createInfixExpression(int, int, int)
- */
- public final void createInfixExpression(ForExpression forExpression, InfixOperator operator, int extendedOperandCount) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- push(InternalInfixOperandType.INFIX_LAST_OPERAND);
- push(operator);
- push(InternalExpressionTypes.INFIX_EXPRESSION);
- int i = extendedOperandCount;
- while (i-- > 0) {
- push(InternalInfixOperandType.INFIX_OTHER_OPERAND);
- push(operator);
- push(InternalExpressionTypes.INFIX_EXPRESSION);
- }
- push(InternalInfixOperandType.INFIX_LEFT_OPERAND);
- push(operator);
- push(InternalExpressionTypes.INFIX_EXPRESSION);
-
- i = extendedOperandCount;
- while (i-- > 0) {
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.INFIX_EXTENDED);
- }
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.INFIX_RIGHT);
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.INFIX_LEFT);
- processExpression(); // See if previous expression is ready for processing.
- } 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(ForExpression forExpression, String type) throws IllegalStateException {
- pushInstanceof(forExpression, getProxyBeanType(type)); // Push this onto the local stack to wait for completion.
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createInstanceofExpression(org.eclipse.jem.internal.proxy.initParser.tree.ForExpression, org.eclipse.jem.internal.proxy.core.IProxyBeanType)
- */
- public final void createInstanceofExpression(ForExpression forExpression, IProxyBeanType type) throws IllegalStateException, IllegalArgumentException {
- pushInstanceof(forExpression, type); // Push this onto the local stack to wait for completion.
- }
-
- /*
- * Push for a cast.
- */
- private void pushInstanceof(ForExpression forExpression, IProxyBeanType type) throws IllegalStateException, IllegalArgumentException {
- try {
- checkForExpression(forExpression);
- validateProxy(type);
- push(type);
- push(InternalExpressionTypes.INSTANCEOF_EXPRESSION);
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.INSTANCEOF_VALUE); // The next expression must be for the instance of expression.
- processExpression();
- } 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(ForExpression forExpression, String name, boolean hasReceiver, int argumentCount)
- throws IllegalStateException, IllegalArgumentException {
- try {
- // Only for string methodnames is this invalid when no receiver because no way to determine receiver. (Don't handle implicit "this" yet for methods).
- // For the accessor that takes a IFieldProxy we can get away with no receiver because the field proxy can determine if static or not, and if not
- // static it will fail at evaluation time.
- if (!hasReceiver)
- throw new IllegalArgumentException(MessageFormat.format(
- ProxyMessages.Expression_MethodsNeedReceiver_EXC_, new Object[] { name}));
-
- pushMethodInvocation(forExpression, name, hasReceiver, argumentCount);
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /**
- * @param forExpression
- * @param method String for method name, IMethodProxy otherwise.
- * @param hasReceiver
- * @param argumentCount
- * @throws ThrowableProxy
- * @throws NoExpressionValueException
- *
- * @since 1.1.0
- */
- private void pushMethodInvocation(ForExpression forExpression, Object method, boolean hasReceiver, int argumentCount) throws IllegalArgumentException, IllegalStateException {
- try {
- checkForExpression(forExpression);
- 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(method);
- push(InternalExpressionTypes.METHOD_EXPRESSION);
-
- pushForExpression(PROCESS_EXPRESSION);
- while (argumentCount-- > 0)
- pushForExpression(ForExpression.METHOD_ARGUMENT);
- if (hasReceiver)
- pushForExpression(ForExpression.METHOD_RECEIVER);
- processExpression(); // See if previous expression is ready for processing.
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrefixExpression(int, org.eclipse.jem.internal.proxy.initParser.tree.PrefixOperator)
- */
- public final void createPrefixExpression(ForExpression forExpression, PrefixOperator operator) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- push(operator);
- push(InternalExpressionTypes.PREFIX_EXPRESSION);
-
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.PREFIX_OPERAND);
- processExpression(); // See if previous expression is ready for processing.
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /**
- * Create a new instance using the initialization string. The result must be compatible with the
- * given type. This is not on the IExpression interface because it is not for use of regular
- * customers. It is here for the allocation processer to create entries that are just strings.
- * <p>
- * This is not customer advanced API. This API for the implementers of registries and expression subclasses.
- *
- * @param forExpression
- * @param initializationString
- * @param type
- * @throws IllegalStateException
- * @throws IllegalArgumentException
- *
- * @since 1.1.0
- */
- public final void createNewInstance(ForExpression forExpression, String initializationString, IProxyBeanType type) throws IllegalStateException, IllegalArgumentException{
- try {
- checkForExpression(forExpression);
- validateProxy(type);
- pushNewInstanceToProxy(initializationString, type);
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createNull(int)
- */
- public final void createNull(ForExpression forExpression) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- pushToProxy(null);
- processExpression(); // See if previous expression is ready for processing.
- } 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(ForExpression forExpression, String type) throws IllegalStateException {
- createProxyExpression(forExpression, getProxyBeanType(type));
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createTypeReceiver(java.lang.String)
- */
- public final void createTypeReceiver(String type) throws IllegalStateException {
- pushTypeReceiver(getProxyBeanType(type));
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createTypeReceiver(org.eclipse.jem.internal.proxy.core.IProxyBeanType)
- */
- public final void createTypeReceiver(IProxyBeanType type) throws IllegalStateException, IllegalArgumentException {
- validateProxy(type);
- pushTypeReceiver(type);
- }
-
- /*
- * Push for a type receiver.
- * @param type
- *
- * @since 1.0.0
- */
- private void pushTypeReceiver(IProxyBeanType type) throws IllegalStateException {
- 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(ForExpression.FIELD_RECEIVER))
- checkForExpression(ForExpression.FIELD_RECEIVER);
- else
- checkForExpression(ForExpression.METHOD_RECEIVER);
-
- pushTypeReceiverToProxy(type);
- processExpression(); // See if previous expression is ready for processing.
- } 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(ForExpression forExpression, boolean value) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- pushToProxy(beanProxyFactory.createBeanProxyWith(value));
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, char)
- */
- public final void createPrimitiveLiteral(ForExpression forExpression, char value) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- pushToProxy(beanProxyFactory.createBeanProxyWith(value));
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, byte)
- */
- public final void createPrimitiveLiteral(ForExpression forExpression, byte value) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- pushToProxy(beanProxyFactory.createBeanProxyWith(value));
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, double)
- */
- public final void createPrimitiveLiteral(ForExpression forExpression, double value) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- pushToProxy(beanProxyFactory.createBeanProxyWith(value));
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, float)
- */
- public final void createPrimitiveLiteral(ForExpression forExpression, float value) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- pushToProxy(beanProxyFactory.createBeanProxyWith(value));
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, int)
- */
- public final void createPrimitiveLiteral(ForExpression forExpression, int value) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- pushToProxy(beanProxyFactory.createBeanProxyWith(value));
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, long)
- */
- public final void createPrimitiveLiteral(ForExpression forExpression, long value) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- pushToProxy(beanProxyFactory.createBeanProxyWith(value));
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createPrimitiveLiteral(int, short)
- */
- public final void createPrimitiveLiteral(ForExpression forExpression, short value) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- pushToProxy(beanProxyFactory.createBeanProxyWith(value));
- processExpression();
- } 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(ForExpression forExpression, String value) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- pushToProxy(beanProxyFactory.createBeanProxyWith(value));
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createProxyExpression(int, org.eclipse.jem.internal.proxy.core.IProxy)
- */
- public final void createProxyExpression(ForExpression forExpression, IProxy proxy) throws IllegalStateException, IllegalArgumentException {
- try {
- checkForExpression(forExpression);
- validateProxy(proxy);
- pushToProxy(proxy);
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createAssignmentExpression(int)
- */
- public final void createAssignmentExpression(ForExpression forExpression) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- push(InternalExpressionTypes.ASSIGNMENT_EXPRESSION);
-
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.ASSIGNMENT_RIGHT);
- pushForExpression(ForExpression.ASSIGNMENT_LEFT);
- processExpression(); // See if previous expression is ready for processing.
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createAssignmentExpression(int)
- */
- public final ExpressionProxy createProxyAssignmentExpression(ForExpression forExpression) throws IllegalStateException {
- try {
- checkForExpression(forExpression);
- ExpressionProxy proxy = allocateExpressionProxy(NORMAL_EXPRESSION_PROXY);
- push(proxy);
- push(InternalExpressionTypes.ASSIGNMENT_PROXY_EXPRESSION);
-
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.ASSIGNMENT_RIGHT);
- processExpression(); // See if previous expression is ready for processing.
- return proxy;
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /**
- * Called by registries to create an expression proxy for a bean type. It is not in the interface because it should
- * only be called by the proxy registry to create an expression proxy. It shouldn't be called outside of the registries
- * because there may already exist in the registry the true IBeanTypeProxy, and that one should be used instead.
- * <p>
- * This is not customer advanced API. This API for the implementers of registries and expression subclasses.
- *
- * @param typeName
- * @return expression proxy that is hooked up and will notify when resolved. It can be called at any time. The resolution will occur at this point in the
- * execution stack, but since it will not interfere with the stack this is OK, other than it could throw a ClassNotFoundException on the
- * execution.
- *
- * @since 1.1.0
- */
- public final IProxyBeanType createBeanTypeExpressionProxy(String typeName) {
- IBeanTypeExpressionProxy proxy = (IBeanTypeExpressionProxy) allocateExpressionProxy(BEANTYPE_EXPRESSION_PROXY);
- proxy.setTypeName(typeName);
- // This can be sent at any time. It doesn't matter what is on the expression stack. It will be sent to be resolved immediately.
- pushBeanTypeToProxy(proxy);
- return proxy;
- }
-
- /**
- * Called by registries to create an expression proxy for a method. It is not in the interface because it should
- * only be called by the proxy registry to create an expression proxy. It shouldn't be called outside of the registries
- * because there may already exist in the registry the true IMethodProxy, and that one should be used instead.
- * <p>
- * This is not customer advanced API. This API for the implementers of registries and expression subclasses.
- *
- * @param declaringType
- * @param methodName
- * @param parameterTypes parameter types or <code>null</code> if no parameter types.
- * @return
- *
- * @throws IllegalArgumentException
- * @since 1.1.0
- */
- public final IProxyMethod createMethodExpressionProxy(IProxyBeanType declaringType, String methodName, IProxyBeanType[] parameterTypes) throws IllegalArgumentException{
- validateProxy(declaringType);
- if (parameterTypes != null && parameterTypes.length > 0) {
- for (int i = 0; i < parameterTypes.length; i++) {
- validateProxy(parameterTypes[i]);
- }
- }
- ExpressionProxy proxy = allocateExpressionProxy(METHOD_EXPRESSION_PROXY);
- // This can be sent at any time. It doesn't matter what is on the expression stack. It will be sent to be resolved immediately.
- pushMethodToProxy(proxy, declaringType, methodName, parameterTypes);
- return (IProxyMethod) proxy;
- }
-
- /**
- * Called by registries to create an expression proxy for a field. It is not in the interface because it should
- * only be called by the proxy registry to create an expression proxy. It shouldn't be called outside of the registries
- * because there may already exist in the registry the true IFieldProxy, and that one should be used instead.
- * <p>
- * This is not customer advanced API. This API for the implementers of registries and expression subclasses.
- *
- * @param declaringType
- * @param fieldName
- * @return
- *
- * @throws IllegalArgumentException
- * @since 1.1.0
- */
- public final IProxyField createFieldExpressionProxy(IProxyBeanType declaringType, String fieldName) throws IllegalArgumentException {
- validateProxy(declaringType);
- ExpressionProxy proxy = allocateExpressionProxy(FIELD_EXPRESSION_PROXY);
- // This can be sent at any time. It doesn't matter what is on the expression stack. It will be sent to be resolved immediately.
- pushFieldToProxy(proxy, declaringType, fieldName);
- return (IProxyField) proxy;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createProxyReassignmentExpression(org.eclipse.jem.internal.proxy.initParser.tree.ForExpression, org.eclipse.jem.internal.proxy.core.ExpressionProxy)
- */
- public final void createProxyReassignmentExpression(ForExpression forExpression, ExpressionProxy proxy) throws IllegalStateException, IllegalArgumentException {
- try {
- checkForExpression(forExpression);
- if (!proxy.isValidForReassignment())
- throw new IllegalArgumentException(MessageFormat.format(ProxyMessages.Expression_CreateProxyReassignmentExpression_InvalidForReassignment_EXC_, new Object[]{proxy.toString()}));
- push(proxy);
- push(InternalExpressionTypes.ASSIGNMENT_PROXY_EXPRESSION);
-
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.ASSIGNMENT_RIGHT);
- processExpression(); // See if previous expression is ready for processing.
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- protected static final int NORMAL_EXPRESSION_PROXY = 0;
- protected static final int BEANTYPE_EXPRESSION_PROXY = 1;
- protected static final int METHOD_EXPRESSION_PROXY = 2;
- protected static final int FIELD_EXPRESSION_PROXY = 3;
- /**
- * Allocate a new ExpressionProxy
- * @return new ExpressionProxy.
- *
- * @since 1.1.0
- */
- protected final ExpressionProxy allocateExpressionProxy(int proxyType) {
- if (expressionProxies == null)
- expressionProxies = new ArrayList();
- // It is very important that this always creates a proxy id that is greater than all previous. This is
- // so that it can be assured that proxies will be resolved in order of creation.
- // Currently this is done here by using expressionProxies.size().
- ExpressionProxy proxy = createExpressionProxy(proxyType, expressionProxies.size());
- expressionProxies.add(proxy);
- return proxy;
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createFieldAccess(org.eclipse.jem.internal.proxy.initParser.tree.ForExpression, org.eclipse.jem.internal.proxy.core.IProxyField, boolean)
- */
- public final void createFieldAccess(ForExpression forExpression, IProxyField fieldProxy, boolean hasReceiver) throws IllegalStateException, IllegalArgumentException {
- validateProxy(fieldProxy);
- pushFieldAccess(forExpression, fieldProxy, hasReceiver);
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createMethodInvocation(org.eclipse.jem.internal.proxy.initParser.tree.ForExpression, org.eclipse.jem.internal.proxy.core.IProxyMethod, boolean, int)
- */
- public final void createMethodInvocation(ForExpression forExpression, IProxyMethod methodProxy, boolean hasReceiver, int argumentCount) throws IllegalArgumentException,
- IllegalStateException {
- validateProxy(methodProxy);
- pushMethodInvocation(forExpression, methodProxy, hasReceiver, argumentCount);
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createSimpleFieldAccess(org.eclipse.jem.internal.proxy.core.IProxyField, org.eclipse.jem.internal.proxy.core.IProxy)
- */
- public final ExpressionProxy createSimpleFieldAccess(IProxyField field, IProxy receiver) throws IllegalStateException, IllegalArgumentException {
- validateProxy(field);
- validateProxy(receiver);
- ExpressionProxy result = createProxyAssignmentExpression(ForExpression.ROOTEXPRESSION);
- createFieldAccess(ForExpression.ASSIGNMENT_RIGHT, field, receiver != null);
- if (receiver != null)
- createProxyExpression(ForExpression.FIELD_RECEIVER, receiver);
- return result;
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createSimpleFieldSet(org.eclipse.jem.internal.proxy.core.IProxyField, org.eclipse.jem.internal.proxy.core.IProxy, org.eclipse.jem.internal.proxy.core.IProxy, boolean)
- */
- public final ExpressionProxy createSimpleFieldSet(IProxyField field, IProxy receiver, IProxy value, boolean wantResult) throws IllegalStateException, IllegalArgumentException {
- validateProxy(field);
- validateProxy(receiver);
- ExpressionProxy result = null;
- ForExpression forExpression = ForExpression.ROOTEXPRESSION;
- if (wantResult) {
- result = createProxyAssignmentExpression(forExpression);
- forExpression = ForExpression.ASSIGNMENT_RIGHT;
- }
- createAssignmentExpression(forExpression);
- createFieldAccess(ForExpression.ASSIGNMENT_LEFT, field, receiver != null);
- if (receiver != null)
- createProxyExpression(ForExpression.FIELD_RECEIVER, receiver);
- createProxyExpression(ForExpression.ASSIGNMENT_RIGHT, value);
- return result;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createSimpleMethodInvoke(org.eclipse.jem.internal.proxy.core.IMethodProxy, org.eclipse.jem.internal.proxy.core.IProxy, org.eclipse.jem.internal.proxy.core.IProxy[], boolean)
- */
- public final ExpressionProxy createSimpleMethodInvoke(IProxyMethod method, IProxy receiver, IProxy[] arguments, boolean wantResult)
- throws IllegalStateException, IllegalArgumentException {
- validateProxy(method);
- validateProxy(receiver);
- if (arguments != null && arguments.length > 0) {
- for (int i = 0; i < arguments.length; i++) {
- validateProxy(arguments[i]);
- }
- }
- ForExpression nextExpression = ForExpression.ROOTEXPRESSION;
- ExpressionProxy result = null;
- if (wantResult) {
- result = createProxyAssignmentExpression(nextExpression);
- nextExpression = ForExpression.ASSIGNMENT_RIGHT;
- }
- createMethodInvocation(nextExpression, method, receiver != null, arguments != null ? arguments.length : 0);
- if (receiver != null)
- createProxyExpression(ForExpression.METHOD_RECEIVER, receiver);
- if (arguments != null) {
- for (int i = 0; i < arguments.length; i++) {
- createProxyExpression(ForExpression.METHOD_ARGUMENT, arguments[i]);
- }
- }
- return result;
- }
-
- private int subexpressionNumber = -1; // Current subexpression number. This is always incrementing.
-
- public void createSubexpression() throws IllegalStateException {
- try {
- // Subexpressions are special, they can be anywhere.
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(SUBEXPRESSIONEND_EXPRESSION);
- pushForExpression(ForExpression.ROOTEXPRESSION);
-
- pushSubexpressionBeginToProxy(++subexpressionNumber);
- push(new Integer(subexpressionNumber));
- push(InternalExpressionTypes.SUBEXPRESSION_END_EXPRESSION);
- processExpression();
- return;
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- public void createSubexpressionEnd() throws IllegalStateException {
- try {
- checkForExpression(ForExpression.ROOTEXPRESSION);
- popForExpression(); // Remove the root expression since block is done.
- checkForExpression(SUBEXPRESSIONEND_EXPRESSION); // This needs to be next for it to be valid.
- processExpression(); // Now let it handle the previously pushed end subexpression, containing the subexpression number being ended.
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
-
- private int tryNumber = -1; // Current try number. This is always incrementing.
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createTry()
- */
- public final void createTry() throws IllegalStateException {
- try {
- checkForExpression(ForExpression.ROOTEXPRESSION);
- pushForExpression(PROCESS_EXPRESSION); // Set up so that when reached we can process the TRY_END that we've pushed data for later in this method.
- pushForExpression(TRYEND_EXPRESSION); // Must get a try end before we can process it.
- pushForExpression(TRYCATCH_EXPRESSION); // Must get a catch/finally clause (or try end, which knows how to handle this).
- pushForExpression(ForExpression.ROOTEXPRESSION); // Expecting root expressions for the try clause.
-
- pushTryBeginToProxy(++tryNumber);
- push(new Integer(tryNumber));
- push(InternalExpressionTypes.TRY_END_EXPRESSION);
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createTryCatchClause(org.eclipse.jem.internal.proxy.core.IProxyBeanType, boolean)
- */
- public final ExpressionProxy createTryCatchClause(IProxyBeanType exceptionType, boolean wantExceptionReturned)
- throws IllegalStateException, IllegalArgumentException {
- validateProxy(exceptionType);
- return pushTryCatch(exceptionType, wantExceptionReturned);
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createTryCatchClause(java.lang.String, boolean)
- */
- public final ExpressionProxy createTryCatchClause(String exceptionType, boolean wantExceptionReturned)
- throws IllegalStateException {
- return pushTryCatch(getProxyBeanType(exceptionType), wantExceptionReturned);
- }
-
- /**
- * @param exceptionType
- * @param wantExceptionReturned
- * @return
- * @throws IllegalStateException
- *
- * @since 1.1.0
- */
- private ExpressionProxy pushTryCatch(IProxyBeanType exceptionType, boolean wantExceptionReturned) throws IllegalStateException {
- try {
- checkForExpression(ForExpression.ROOTEXPRESSION);
- popForExpression(); // Remove the root expression since try or previous catch clause is done.
- checkForExpression(TRYCATCH_EXPRESSION); // This needs to be next for it to be valid.
- pushForExpression(TRYCATCH_EXPRESSION); // Set up for a following catch/finally clause.
- pushForExpression(ForExpression.ROOTEXPRESSION); // Root expressions are next for the catch clause.
-
- int tryNumber = ((Integer) peek(2)).intValue(); // Get the try#. It should be in this place on the stack.
-
- ExpressionProxy ep = null;
- if (wantExceptionReturned)
- ep = allocateExpressionProxy(NORMAL_EXPRESSION_PROXY);
- pushTryCatchClauseToProxy(tryNumber, exceptionType, ep);
-
- processExpression();
- return ep;
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createTryEnd()
- */
- public final void createTryEnd() throws IllegalStateException {
- try {
- checkForExpression(ForExpression.ROOTEXPRESSION);
- popForExpression(); // Remove the root expression since try or previous catch clause is done.
- if (peekForExpression(TRYCATCH_EXPRESSION))
- checkForExpression(TRYCATCH_EXPRESSION); // This may of been next if no finally clause was added. If a finally clause was added this would not be here.
- checkForExpression(TRYEND_EXPRESSION); // And this needs to be after that to be valid.
-
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createTryFinallyClause()
- */
- public final void createTryFinallyClause() throws IllegalStateException {
- try {
- checkForExpression(ForExpression.ROOTEXPRESSION);
- popForExpression(); // Remove the root expression since try or previous catch clause is done.
- checkForExpression(TRYCATCH_EXPRESSION); // This needs to be next for it to be valid.
- pushForExpression(ForExpression.ROOTEXPRESSION); // Root expressions are next for the finally clause.
-
- int tryNumber = ((Integer) peek(2)).intValue(); // Get the try#. It should be in this place on the stack.
-
- pushTryFinallyClauseToProxy(tryNumber);
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
-
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createRethrow()
- */
- public final void createRethrow() throws IllegalStateException {
- try {
- checkForExpression(ForExpression.ROOTEXPRESSION);
- popForExpression(); // Remove the root expression since try or previous catch clause is done.
- checkForExpression(TRYCATCH_EXPRESSION); // This needs to be next for it to be valid.
- // It is in a valid state, so put the catch and root back on so that things work correctly.
- pushForExpression(TRYCATCH_EXPRESSION);
- pushForExpression(ForExpression.ROOTEXPRESSION);
-
- int tryNumber = ((Integer) peek(2)).intValue(); // Get the try#. It should be in this place on the stack.
-
- pushRethrowToProxy(tryNumber);
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jem.internal.proxy.core.IExpression#createThrow()
- */
- public final void createThrow() throws IllegalStateException {
- try {
- checkForExpression(ForExpression.ROOTEXPRESSION);
- push(InternalExpressionTypes.THROW_EXPRESSION);
- pushForExpression(PROCESS_EXPRESSION);
- pushForExpression(ForExpression.THROW_OPERAND); // The next expression must be for the throw value.
- processExpression();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
-
- public final int mark() throws IllegalStateException {
- try {
- checkForExpression(ForExpression.ROOTEXPRESSION);
- ++highestMarkID;
- currentMarkEntry = new MarkEntry();
- currentMarkEntry.markID = highestMarkID;
- currentMarkEntry.controlStackPos = controlStack.size() - 1;
- currentMarkEntry.nextExpressionStackPos = nextForExpressionStackPos;
- currentMarkEntry.expressionProxiesPos = expressionProxies != null ? expressionProxies.size() - 1 : -1;
- if (markEntries == null)
- markEntries = new ArrayList(5);
- markEntries.add(currentMarkEntry);
- pushMarkToProxy(highestMarkID);
- return highestMarkID;
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- public void endMark(int markNumber) throws IllegalStateException {
- if (isValid()) {
- // Can only do a valid end mark if we are at root. If not at root, we fall through and treat as invalid.
- if (peekForExpression(ForExpression.ROOTEXPRESSION)) {
- checkForExpression(ForExpression.ROOTEXPRESSION); // Now remove it if it should be removed.
- // If the current mark number is not the same as the incoming mark number, we have improper nesting.
- if (currentMarkEntry == null || currentMarkEntry.markID != markNumber)
- throwInvalidMarkNesting(); // We have improper nesting.
- // We are popping the current mark. Since we are valid, just move up one in the mark stack.
- MarkEntry me = (MarkEntry) markEntries.remove(markEntries.size()-1);
- if (!markEntries.isEmpty())
- currentMarkEntry = (MarkEntry) markEntries.get(markEntries.size()-1);
- else
- currentMarkEntry = null;
- pushEndmarkToProxy(markNumber, false);
- if (me.controlStackPos != controlStack.size()-1 || me.nextExpressionStackPos != nextForExpressionStackPos)
- throwInvalidMarkNesting(); // The stacks should be back to the same size at this point for a valid end mark.
- return;
- }
- }
-
- // It was invalid, or became invalid.
- if (markEntries == null)
- throwInvalidMarkNesting(); // We have no marks, so this is an invalid end mark.
-
- // We are invalid, need to pop to the given markNumber.
- // Starting from the end we search back to find the entry for the given mark number. We do it
- // from the end because it is more likely to be closer to the end than to the beginning.
- for (int i = markEntries.size()-1; i >=0; i--) {
- MarkEntry me = (MarkEntry) markEntries.get(i);
- if (me.markID == markNumber) {
- // Found it.
- // Trim the control stack down to the size at time of mark. (No easy way to do this other than repeated remove's.
- // We do it backwards to eliminate repeated shuffling of entries.
- for (int j = controlStack.size()-1; j > me.controlStackPos; j--) {
- controlStack.remove(j);
- }
-
- // Trim the expression stack. This is simple, just reset the next entry pointer.
- nextForExpressionStackPos = me.nextExpressionStackPos;
-
- if (expressionProxies != null) {
- // Now we need to mark all of the expression proxies that occured after the mark as
- // not resolved (since someone may be listening), and remove them, and reuse the proxies.
- for (int j = expressionProxies.size()-1; j > me.expressionProxiesPos; j--) {
- ExpressionProxy proxy = (ExpressionProxy) expressionProxies.remove(j);
- if (proxy != null && proxy.hasListeners())
- fireProxyNotResolved(proxy);
- }
- }
-
- // Now that we know it is valid, we want to remove all of the mark entries above it in the stack
- // since those are now invalid. We couldn't remove them as we were searching for the entry because
- // if the entry wasn't found we didn't want to wipe out the probably valid ones.
- for (int j = markEntries.size()-1; j >= i; j--) {
- markEntries.remove(j);
- }
-
- if (!markEntries.isEmpty())
- currentMarkEntry = (MarkEntry) markEntries.get(markEntries.size()-1);
- else
- currentMarkEntry = null;
- pushEndmarkToProxy(markNumber, true);
- expressionValid = true;
- return;
- }
- }
- throwInvalidMarkNesting(); // The mark number wasn't found, so this is an invalid end mark.
- }
-
- /**
- * Begin the transfer of the expression to another thread.
- * <p>
- * This is used when the expression needs to continue to be built up, but it needs
- * to be done on a different thread. The reason for doing something special other
- * than just using it on the other thread is that some proxy registries connections are
- * tied through the thread. If you switched to another thread the connections would not
- * be properly set up.
- * This is not on the IExpression interface because even though it is API, it is tricky
- * to use and so not exposed to everyone. Users can legitimately cast to Expression and
- * use this as API for advanced use.
- * <p>
- * This is used to begin the transfer. It puts it into a state ready for the transfer. Calling this
- * method will cause a synchronization of the expression up to the current level. This means
- * that it will not return until the expression has been completely processed in the proxy registry
- * up to this point. Typically the connection is a pipe where the instructions are just pushed onto
- * it and the caller is not held up waiting for the registry to process it.
- * <p>
- * Then when the other thread is done, it will call beginTransferThread itself to signal that it is done
- * and that the old thread can pick it up. Then the old thread will call transferThread to pick up processing.
- * <p>
- * It will be:
- * <pre><code>
- * ... expression stuff ...
- * expression.beginTransferThread()
- * ... do what is necessary to get to the other thread ...
- * ... on other thread:
- * expression.transferThread();
- * try {
- * ... do your expression stuff on this thread ...
- * } finally {
- * expression.beginTransferThread(); // This is to return it to old thread.
- * }
- * ... tell old thread to pick up ...
- * ... back on old thread:
- * expression.transferThread();
- * ... do more expression stuff ...
- * expression.invokeExpression();
- * </code></pre>
- *
- * @throws IllegalStateException
- * @throws ThrowableProxy Thrown if there was an exception with the remote vm during this request.
- * @since 1.1.0
- */
- public final void beginTransferThread() throws IllegalStateException, ThrowableProxy {
- try {
- pushForExpression(THREADTRANSFER_EXPRESSION);
- pushBeginTransferThreadToProxy();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
- /**
- * Transfer the expression to the current thread.
- * <p>
- * This is called to actually transfer to the current thread. It must be the next call against
- * the expression after the beginTransferThread, but on the new thread.
- * <p>
- * This is not on the IExpression interface because even though it is API, it is tricky
- * to use and so not exposed to everyone. Users can legitimately cast to Expression and
- * use this as API for advanced use.
- * @see Expression#beginTransferThread() for a full explanation.
- * @throws IllegalStateException
- *
- * @since 1.1.0
- */
- public final void transferThread() throws IllegalStateException {
- try {
- checkForExpression(THREADTRANSFER_EXPRESSION);
- pushTransferThreadToProxy();
- } catch (RuntimeException e) {
- markInvalid();
- throw e;
- }
- }
-
-
- /**
- * Get the IProxyBeanType for the type string sent in.
- * @param type
- * @return
- *
- * @since 1.1.0
- */
- protected IProxyBeanType getProxyBeanType(String type) {
- return getRegistry().getBeanTypeProxyFactory().getBeanTypeProxy(this, type);
- }
-
- /**
- * Create the expression proxy subclass that is applicable for this kind of processor.
- * @param proxyType type of proxy. {@link Expression#NORMAL_EXPRESSION_PROXY
- * @param proxyID the id of the new expression proxy.
- *
- * @return
- *
- * @since 1.1.0
- */
- protected abstract ExpressionProxy createExpressionProxy(int proxyType, int proxyID);
-
- /**
- * 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
- *
- * @since 1.0.0
- */
- protected abstract void pushToProxy(IProxy proxy);
-
- /**
- * Tell the other side we are complete. This will always be called after expression evaluation, or
- * if expression was prematurely closed.
- * <p>
- * <b>Note:</b> The implementation must be able to handle multiple invocations, where the first call is a valid close and any
- * subsequent call should be ignored.
- *
- * @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.
- * <p>
- * <b>Note:</b> The expression proxies MUST be resolved (callbacks called) in the order they are found in the expressionProxies list. This
- * is so that the contract is followed that resolution notifications will occur in the order of creation.
- *
- * @param proxycount Number of Expression Proxies that need a callback.
- * @param list of expression proxies. If proxycount > 0, then process the non-null entries in the list. They will be of type ExpressionProxy.
- * @throws ThrowableProxy
- *
- * @since 1.0.0
- */
- protected abstract void pushInvoke(int proxycount, List expressionProxies) throws ThrowableProxy, NoExpressionValueException;
-
- /**
- * Pull the top expression value from the evaluation stack. It will also under
- * the covers call closeProxy. It also must process the expression proxy callbacks. It must do the expression proxy callbacks first, and then
- * process the result value. If an error had occured sometime during processing, it should still process the proxy callbacks before throwing
- * an exception.
- * <p>
- * <b>Note:</b> The expression proxies MUST be resolved (callbacks called) in the order they are found in the expressionProxies list. This
- * is so that the contract is followed that resolution notifications will occur in the order of creation. Also <b>REQUIRED</b> is that
- * the entire list must be processed of proxies must be processed by this call. It cannot do some or none.
- *
- * @param proxycount Number of Expression Proxies that need a callback.
- * @param list of expression proxies. If proxycount > 0, then process the non-null entries in the list. They will be of type ExpressionProxy.
- * @return The top level evaluation stack value.
- * @throws ThrowableProxy
- * @throws NoExpressionValueException
- *
- * @since 1.0.0
- */
- protected abstract IBeanProxy pullProxyValue(int proxycount, List expressionProxies) 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.
- *
- * @since 1.0.0
- */
- protected abstract void pushCastToProxy(IProxyBeanType type);
-
- /**
- * 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.
- *
- * @since 1.0.0
- */
- protected abstract void pushInstanceofToProxy(IProxyBeanType type);
-
- /**
- * 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.
- * @param operandType The operand type. left, other, or last.
- *
- * @since 1.0.0
- */
- protected abstract void pushInfixToProxy(InfixOperator operator, InternalInfixOperandType operandType);
-
- /**
- * 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
- *
- * @see IExpressionConstants#PRE_MINUS
- * @since 1.0.0
- */
- protected abstract void pushPrefixToProxy(PrefixOperator operator);
-
-
- /**
- * Push to proxy the array access. The result will be placed onto the evaluation stack.
- *
- * @param indexCount
- *
- * @since 1.0.0
- */
- protected abstract void pushArrayAccessToProxy(int indexCount);
-
- /**
- * Push to proxy the array creation. The result will be placed onto the evaluation stack.
- * @param type The array type.
- * @param dimensionCount
- *
- * @since 1.0.0
- */
- protected abstract void pushArrayCreationToProxy(IProxyBeanType type, int dimensionCount);
-
- /**
- * Push to proxy the array initializer. The resulting array will be placed onto the evaluation stack.
- * @param type The array type. (must be an array type).
- * @param stripDimCount the number of dimensions that must be stripped from the array type. This is needed
- * because the first array initializer needs to be for the component type of the array (array minus one dimension), and
- * each initializer after that needs one more dimension stripped off. But since we are working with possible expression
- * proxies for "type", we can't create the appropriate component types of the array. So we need to tell the
- * processor how many dims to strip from the original type (which is what is sent in on every initializer push, the original type).
- * @param expressionCount
- *
- * @since 1.0.0
- */
- protected abstract void pushArrayInitializerToProxy(IProxyBeanType type, int stripDimCount, int expressionCount);
-
- /**
- * Push to proxy the class instance creation. The resulting class instance will be placed onto the evaluation stack.
- *
- * @param type Class type.
- * @param argumentCount The number of arguments.
- *
- * @since 1.0.0
- */
- protected abstract void pushClassInstanceCreationToProxy(IProxyBeanType type, int argumentCount);
-
- /**
- * 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.
- *
- * @since 1.0.0
- */
- protected abstract void pushTypeReceiverToProxy(IProxyBeanType type);
-
- /**
- * Push to proxy the field access. The result value will be placed onto the evaluation stack.
- * @param field The name of the field if string, or an IFieldProxy.
- * @param hasReceiver Has receiver flag.
- *
- * @since 1.0.0
- */
- protected abstract void pushFieldAccessToProxy(Object field, boolean hasReceiver);
-
- /**
- * Push to proxy the method invocation. The result value will be placed onto the evaluation stack.
- *
- * @param method String for method name or IProxyMethod
- * @param hasReceiver
- * @param argCount
- *
- * @since 1.0.0
- */
- protected abstract void pushMethodInvocationToProxy(Object method, boolean hasReceiver, int argCount);
-
- /**
- * 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.
- *
- * @since 1.0.0
- */
- protected abstract void pushConditionalToProxy(InternalConditionalOperandType expressionType);
-
- /**
- * Push to the proxy the expression proxy. Whatever the last expression value is will be assigned to the ExpressionProxy.
- *
- * @param proxy
- *
- * @since 1.1.0
- */
- protected abstract void pushAssignmentToProxy(ExpressionProxy proxy);
-
- /**
- * Push the assignment expression. The operands are already on the stack.
- *
- * @since 1.1.0
- */
- protected abstract void pushAssignmentToProxy();
-
-
- /**
- * Push the begin block expression.
- * @param blockNumber
- *
- * @since 1.1.0
- */
- protected abstract void pushBlockBeginToProxy(int blockNumber);
-
- /**
- * Push the end block expression.
- * @param blockNumber
- *
- * @since 1.1.0
- */
- protected abstract void pushBlockEndToProxy(int blockNumber);
-
- /**
- * Push the break block expression.
- * @param blockNumber
- *
- * @since 1.1.0
- *
- */
- protected abstract void pushBlockBreakToProxy(int blockNumber);
-
- /**
- * Push the begin try expression.
- * @param tryNumber
- *
- * @since 1.1.0
- */
- protected abstract void pushTryBeginToProxy(int tryNumber);
-
- /**
- * Push the catch clause to proxy.
- * @param tryNumber
- * @param exceptionType
- * @param ep ExpressionProxy to be assigned with the exception or <code>null</code> if exception is not to be assigned.
- *
- * @since 1.1.0
- */
- protected abstract void pushTryCatchClauseToProxy(int tryNumber, IProxyBeanType exceptionType, ExpressionProxy ep);
-
- /**
- * Push the finally clause to proxy.
- * @param tryNumber
- *
- * @since 1.1.0
- */
- protected abstract void pushTryFinallyClauseToProxy(int tryNumber);
-
- /**
- * Push try end to proxy.
- * @param tryNumber
- *
- * @since 1.1.0
- */
- protected abstract void pushTryEndToProxy(int tryNumber);
-
- /**
- * Push the throw of the exception to proxy.
- * @param exception
- *
- * @since 1.1.0
- */
- protected abstract void pushThrowToProxy();
-
- /**
- * Push a rethrow to proxy.
- * @param tryNumber
- *
- * @since 1.1.0
- */
- protected abstract void pushRethrowToProxy(int tryNumber);
-
- /**
- * Push the BeanType Expression proxy to be resolved on the execution side.
- * @param proxy
- *
- * @since 1.1.0
- */
- protected abstract void pushBeanTypeToProxy(IBeanTypeExpressionProxy proxy);
-
- /**
- * Push the Method Expression proxy to be resolved on the execution side.
- * @param proxy
- * @param declaringType
- * @param methodName
- * @param parameterTypes parameter types or <code>null</code> if no parameters.
- *
- * @since 1.1.0
- */
- protected abstract void pushMethodToProxy(ExpressionProxy proxy, IProxyBeanType declaringType, String methodName, IProxyBeanType[] parameterTypes);
-
- /**
- * Push the Field Expression Proxy to be resolved on the execution side.
- * @param proxy
- * @param declaringType
- * @param fieldName
- *
- * @since 1.1.0
- */
- protected abstract void pushFieldToProxy(ExpressionProxy proxy, IProxyBeanType declaringType, String fieldName);
-
- /**
- * Push the If test condition to proxy.
- *
- * @since 1.1.0
- */
- protected abstract void pushIfTestToProxy();
-
- /**
- * Push a true or else clause to proxy.
- * @param clauseType
- *
- * @since 1.1.0
- */
- protected abstract void pushIfElseToProxy(InternalIfElseOperandType clauseType);
-
- /**
- * Push to proxy a new instance using an initialization string.
- * @param initializationString
- * @param resultType
- *
- * @since 1.1.0
- */
- protected abstract void pushNewInstanceToProxy(String initializationString, IProxyBeanType resultType);
-
- /**
- * Push the mark id to proxy.
- *
- * @param markID
- *
- * @since 1.1.0
- */
- protected abstract void pushMarkToProxy(int markID);
-
- /**
- * Push the end mark id to proxy.
- *
- * @param markID
- * @param restore <code>true</code> if this is a restore due to error, <code>false</code> if this is just a normal end mark.
- *
- * @since 1.1.0
- */
- protected abstract void pushEndmarkToProxy(int markID, boolean restore);
-
- /**
- * Push the begin transfer thread to proxy.
- *
- *
- * @since 1.1.0
- */
- protected abstract void pushBeginTransferThreadToProxy() throws ThrowableProxy;
-
- /**
- * Push the actual transfer to the current thread to proxy.
- *
- *
- * @since 1.1.0
- */
- protected abstract void pushTransferThreadToProxy();
-
- /**
- * Push the subexpression begin to proxy.
- * @param subexpressionNumber
- *
- * @since 1.1.0
- */
- protected abstract void pushSubexpressionBeginToProxy(int subexpressionNumber);
-
- /**
- * Push the subexpression end to proxy.
- * @param subexpressionNumber
- *
- * @since 1.1.0
- */
- protected abstract void pushSubexpressionEndToProxy(int subexpressionNumber);
-}

Back to the top