Search in sources :

Example 61 with CompileException

use of org.mule.mvel2.CompileException in project mvel by mvel.

the class NewObjectNode method getReducedValue.

public Object getReducedValue(Object ctx, Object thisValue, VariableResolverFactory factory) {
    try {
        if (typeDescr.isArray()) {
            Class cls = findClass(factory, typeDescr.getClassName(), pCtx);
            int[] s = new int[typeDescr.getArrayLength()];
            ArraySize[] arraySize = typeDescr.getArraySize();
            for (int i = 0; i < s.length; i++) {
                s[i] = convert(eval(arraySize[i].value, ctx, factory), Integer.class);
            }
            return newInstance(cls, s);
        } else {
            String[] cnsRes = captureContructorAndResidual(name, 0, name.length);
            List<char[]> constructorParms = parseMethodOrConstructor(cnsRes[0].toCharArray());
            if (constructorParms != null) {
                Class cls = findClass(factory, new String(subset(name, 0, findFirst('(', 0, name.length, name))).trim(), pCtx);
                Object[] parms = new Object[constructorParms.size()];
                for (int i = 0; i < constructorParms.size(); i++) {
                    parms[i] = eval(constructorParms.get(i), ctx, factory);
                }
                Constructor cns = getBestConstructorCandidate(parms, cls, false);
                if (cns == null)
                    throw new CompileException("unable to find constructor for: " + cls.getName(), expr, start);
                for (int i = 0; i < parms.length; i++) {
                    // noinspection unchecked
                    parms[i] = convert(parms[i], cns.getParameterTypes()[i]);
                }
                if (cnsRes.length > 1) {
                    return PropertyAccessor.get(cnsRes[1], cns.newInstance(parms), factory, thisValue, pCtx);
                } else {
                    return cns.newInstance(parms);
                }
            } else {
                Constructor<?> cns = Class.forName(typeDescr.getClassName(), true, pCtx.getParserConfiguration().getClassLoader()).getConstructor(EMPTYCLS);
                if (cnsRes.length > 1) {
                    return PropertyAccessor.get(cnsRes[1], cns.newInstance(), factory, thisValue, pCtx);
                } else {
                    return cns.newInstance();
                }
            }
        }
    } catch (CompileException e) {
        throw e;
    } catch (ClassNotFoundException e) {
        throw new CompileException("unable to resolve class: " + e.getMessage(), expr, start, e);
    } catch (NoSuchMethodException e) {
        throw new CompileException("cannot resolve constructor: " + e.getMessage(), expr, start, e);
    } catch (Exception e) {
        throw new CompileException("could not instantiate class: " + e.getMessage(), expr, start, e);
    }
}
Also used : Constructor(java.lang.reflect.Constructor) CompileException(org.mvel2.CompileException) CompileException(org.mvel2.CompileException)

Example 62 with CompileException

use of org.mule.mvel2.CompileException in project mvel by mvel.

the class Soundslike method getReducedValue.

public Object getReducedValue(Object ctx, Object thisValue, VariableResolverFactory factory) {
    try {
        String i = String.valueOf(soundslike.getReducedValue(ctx, thisValue, factory));
        if (i == null)
            throw new ClassCastException();
        String x = (String) stmt.getReducedValue(ctx, thisValue, factory);
        if (x == null)
            throw new CompileException("not a string: " + stmt.getName(), stmt.getExpr(), stmt.getStart());
        return soundex(i).equals(soundex(x));
    } catch (ClassCastException e) {
        throw new CompileException("not a string: " + soundslike.getName(), soundslike.getExpr(), soundslike.getStart());
    }
}
Also used : CompileException(org.mvel2.CompileException)

Example 63 with CompileException

use of org.mule.mvel2.CompileException in project mvel by mvel.

the class AbstractParser method nextToken.

/**
 * Retrieve the next token in the expression.
 *
 * @return -
 */
protected ASTNode nextToken() {
    try {
        /**
         * If the cursor is at the end of the expression, we have nothing more to do:
         * return null.
         */
        if (!splitAccumulator.isEmpty()) {
            lastNode = (ASTNode) splitAccumulator.pop();
            if (cursor >= end && lastNode instanceof EndOfStatement) {
                return nextToken();
            } else {
                return lastNode;
            }
        } else if (cursor >= end) {
            return null;
        }
        int brace, idx;
        int tmpStart;
        String name;
        /**
         * Because of parser recursion for sub-expression parsing, we sometimes need to remain
         * certain field states.  We do not reset for assignments, boolean mode, list creation or
         * a capture only mode.
         */
        boolean capture = false, union = false;
        if ((fields & ASTNode.COMPILE_IMMEDIATE) != 0) {
            debugSymbols = pCtx.isDebugSymbols();
        }
        if (debugSymbols) {
            if (!lastWasLineLabel) {
                if (pCtx.getSourceFile() == null) {
                    throw new CompileException("unable to produce debugging symbols: source name must be provided.", expr, st);
                }
                if (!pCtx.isLineMapped(pCtx.getSourceFile())) {
                    pCtx.initLineMapping(pCtx.getSourceFile(), expr);
                }
                skipWhitespace();
                if (cursor >= end) {
                    return null;
                }
                int line = pCtx.getLineFor(pCtx.getSourceFile(), cursor);
                if (!pCtx.isVisitedLine(pCtx.getSourceFile(), pCtx.setLineCount(line)) && !pCtx.isBlockSymbols()) {
                    lastWasLineLabel = true;
                    pCtx.visitLine(pCtx.getSourceFile(), line);
                    return lastNode = pCtx.setLastLineLabel(new LineLabel(pCtx.getSourceFile(), line, pCtx));
                }
            } else {
                lastWasComment = lastWasLineLabel = false;
            }
        }
        /**
         * Skip any whitespace currently under the starting point.
         */
        skipWhitespace();
        /**
         * From here to the end of the method is the core MVEL parsing code.  Fiddling around here is asking for
         * trouble unless you really know what you're doing.
         */
        st = cursor;
        Mainloop: while (cursor != end) {
            if (isIdentifierPart(expr[cursor])) {
                capture = true;
                cursor++;
                while (cursor != end && isIdentifierPart(expr[cursor])) cursor++;
            }
            if (capture) {
                String t;
                if (OPERATORS.containsKey(t = new String(expr, st, cursor - st)) && !Character.isDigit(expr[st])) {
                    switch(OPERATORS.get(t)) {
                        case NEW:
                            if (!isIdentifierPart(expr[st = cursor = trimRight(cursor)])) {
                                throw new CompileException("unexpected character (expected identifier): " + expr[cursor], expr, st);
                            }
                            /**
                             * Capture the beginning part of the token.
                             */
                            do {
                                captureToNextTokenJunction();
                                skipWhitespace();
                            } while (cursor < end && expr[cursor] == '[');
                            /**
                             * If it's not a dimentioned array, continue capturing if necessary.
                             */
                            if (cursor < end && !lastNonWhite(']'))
                                captureToEOT();
                            TypeDescriptor descr = new TypeDescriptor(expr, st, trimLeft(cursor) - st, fields);
                            if (pCtx.getFunctions().containsKey(descr.getClassName())) {
                                return lastNode = new NewObjectPrototype(pCtx, pCtx.getFunction(descr.getClassName()));
                            }
                            if (pCtx.hasProtoImport(descr.getClassName())) {
                                return lastNode = new NewPrototypeNode(descr, pCtx);
                            }
                            lastNode = new NewObjectNode(descr, fields, pCtx);
                            skipWhitespace();
                            if (cursor != end && expr[cursor] == '{') {
                                if (!((NewObjectNode) lastNode).getTypeDescr().isUndimensionedArray()) {
                                    throw new CompileException("conflicting syntax: dimensioned array with initializer block", expr, st);
                                }
                                st = cursor;
                                Class egressType = lastNode.getEgressType();
                                if (egressType == null) {
                                    try {
                                        egressType = getClassReference(pCtx, descr);
                                    } catch (ClassNotFoundException e) {
                                        throw new CompileException("could not instantiate class", expr, st, e);
                                    }
                                }
                                cursor = balancedCaptureWithLineAccounting(expr, st, end, expr[cursor], pCtx) + 1;
                                if (tokenContinues()) {
                                    lastNode = new InlineCollectionNode(expr, st, cursor - st, fields, egressType, pCtx);
                                    st = cursor;
                                    captureToEOT();
                                    return lastNode = new Union(expr, st + 1, cursor, fields, lastNode, pCtx);
                                } else {
                                    return lastNode = new InlineCollectionNode(expr, st, cursor - st, fields, egressType, pCtx);
                                }
                            } else if (((NewObjectNode) lastNode).getTypeDescr().isUndimensionedArray()) {
                                throw new CompileException("array initializer expected", expr, st);
                            }
                            st = cursor;
                            return lastNode;
                        case ASSERT:
                            st = cursor = trimRight(cursor);
                            captureToEOS();
                            return lastNode = new AssertNode(expr, st, cursor-- - st, fields, pCtx);
                        case RETURN:
                            st = cursor = trimRight(cursor);
                            captureToEOS();
                            return lastNode = new ReturnNode(expr, st, cursor - st, fields, pCtx);
                        case IF:
                            return captureCodeBlock(ASTNode.BLOCK_IF);
                        case ELSE:
                            throw new CompileException("else without if", expr, st);
                        case FOREACH:
                            return captureCodeBlock(ASTNode.BLOCK_FOREACH);
                        case WHILE:
                            return captureCodeBlock(ASTNode.BLOCK_WHILE);
                        case UNTIL:
                            return captureCodeBlock(ASTNode.BLOCK_UNTIL);
                        case FOR:
                            return captureCodeBlock(ASTNode.BLOCK_FOR);
                        case WITH:
                            return captureCodeBlock(ASTNode.BLOCK_WITH);
                        case DO:
                            return captureCodeBlock(ASTNode.BLOCK_DO);
                        case STACKLANG:
                            return captureCodeBlock(STACKLANG);
                        case PROTO:
                            return captureCodeBlock(PROTO);
                        case ISDEF:
                            st = cursor = trimRight(cursor);
                            captureToNextTokenJunction();
                            return lastNode = new IsDef(expr, st, cursor - st, pCtx);
                        case IMPORT:
                            st = cursor = trimRight(cursor);
                            captureToEOS();
                            ImportNode importNode = new ImportNode(expr, st, cursor - st, pCtx);
                            if (importNode.isPackageImport()) {
                                pCtx.addPackageImport(importNode.getPackageImport());
                            } else {
                                pCtx.addImport(importNode.getImportClass().getSimpleName(), importNode.getImportClass());
                            }
                            return lastNode = importNode;
                        case IMPORT_STATIC:
                            st = cursor = trimRight(cursor);
                            captureToEOS();
                            StaticImportNode staticImportNode = new StaticImportNode(expr, st, trimLeft(cursor) - st, pCtx);
                            pCtx.addImport(staticImportNode.getMethod().getName(), staticImportNode.getMethod());
                            return lastNode = staticImportNode;
                        case FUNCTION:
                            lastNode = captureCodeBlock(FUNCTION);
                            st = cursor + 1;
                            return lastNode;
                        case UNTYPED_VAR:
                            int end;
                            st = cursor + 1;
                            while (true) {
                                captureToEOT();
                                end = cursor;
                                skipWhitespace();
                                if (cursor != end && expr[cursor] == '=') {
                                    if (end == (cursor = st))
                                        throw new CompileException("illegal use of reserved word: var", expr, st);
                                    continue Mainloop;
                                } else {
                                    name = new String(expr, st, end - st);
                                    if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                                        splitAccumulator.add(lastNode = new IndexedDeclTypedVarNode(idx, st, end - st, Object.class, pCtx));
                                    } else {
                                        splitAccumulator.add(lastNode = new DeclTypedVarNode(name, expr, st, end - st, Object.class, fields, pCtx));
                                    }
                                }
                                if (cursor == this.end || expr[cursor] != ',')
                                    break;
                                else {
                                    cursor++;
                                    skipWhitespace();
                                    st = cursor;
                                }
                            }
                            return (ASTNode) splitAccumulator.pop();
                        case CONTAINS:
                            lastWasIdentifier = false;
                            return lastNode = new OperatorNode(Operator.CONTAINS, expr, st, pCtx);
                    }
                }
                skipWhitespace();
                /**
                 * If we *were* capturing a token, and we just hit a non-identifier
                 * character, we stop and figure out what to do.
                 */
                if (cursor != end && expr[cursor] == '(') {
                    cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '(', pCtx) + 1;
                }
                /**
                 * If we encounter any of the following cases, we are still dealing with
                 * a contiguous token.
                 */
                CaptureLoop: while (cursor != end) {
                    switch(expr[cursor]) {
                        case '.':
                            union = true;
                            cursor++;
                            skipWhitespace();
                            continue;
                        case '?':
                            if (lookToLast() == '.' || cursor == start) {
                                union = true;
                                cursor++;
                                continue;
                            } else {
                                break CaptureLoop;
                            }
                        case '+':
                            switch(lookAhead()) {
                                case '+':
                                    name = new String(subArray(st, trimLeft(cursor)));
                                    if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                                        lastNode = new IndexedPostFixIncNode(idx, pCtx);
                                    } else {
                                        lastNode = new PostFixIncNode(name, pCtx);
                                    }
                                    cursor += 2;
                                    expectEOS();
                                    return lastNode;
                                case '=':
                                    name = createStringTrimmed(expr, st, cursor - st);
                                    st = cursor += 2;
                                    captureToEOS();
                                    if (union) {
                                        return lastNode = new DeepAssignmentNode(expr, st = trimRight(st), trimLeft(cursor) - st, fields, ADD, name, pCtx);
                                    } else if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                                        return lastNode = new IndexedAssignmentNode(expr, st, cursor - st, fields, ADD, name, idx, pCtx);
                                    } else {
                                        return lastNode = new OperativeAssign(name, expr, st = trimRight(st), trimLeft(cursor) - st, ADD, fields, pCtx);
                                    }
                            }
                            if (isDigit(lookAhead()) && cursor > 1 && (expr[cursor - 1] == 'E' || expr[cursor - 1] == 'e') && isDigit(expr[cursor - 2])) {
                                cursor++;
                                // capture = true;
                                continue Mainloop;
                            }
                            break CaptureLoop;
                        case '-':
                            switch(lookAhead()) {
                                case '-':
                                    name = new String(subArray(st, trimLeft(cursor)));
                                    if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                                        lastNode = new IndexedPostFixDecNode(idx, pCtx);
                                    } else {
                                        lastNode = new PostFixDecNode(name, pCtx);
                                    }
                                    cursor += 2;
                                    expectEOS();
                                    return lastNode;
                                case '=':
                                    name = new String(expr, st, trimLeft(cursor) - st);
                                    st = cursor += 2;
                                    captureToEOS();
                                    if (union) {
                                        return lastNode = new DeepAssignmentNode(expr, st, cursor - st, fields, SUB, t, pCtx);
                                    } else if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                                        return lastNode = new IndexedOperativeAssign(expr, st, cursor - st, SUB, idx, fields, pCtx);
                                    } else {
                                        return lastNode = new OperativeAssign(name, expr, st, cursor - st, SUB, fields, pCtx);
                                    }
                            }
                            if (isDigit(lookAhead()) && cursor > 1 && (expr[cursor - 1] == 'E' || expr[cursor - 1] == 'e') && isDigit(expr[cursor - 2])) {
                                cursor++;
                                capture = true;
                                continue Mainloop;
                            }
                            break CaptureLoop;
                        /**
                         * Exit immediately for any of these cases.
                         */
                        case '!':
                        case ',':
                        case '"':
                        case '\'':
                        case ';':
                        case ':':
                            break CaptureLoop;
                        // special compact code for recursive parses
                        case '\u00AB':
                        case '\u00BB':
                        case '\u00AC':
                        case '&':
                        case '^':
                        case '|':
                        case '*':
                        case '/':
                        case '%':
                            char op = expr[cursor];
                            if (lookAhead() == '=') {
                                name = new String(expr, st, trimLeft(cursor) - st);
                                st = cursor += 2;
                                captureToEOS();
                                if (union) {
                                    return lastNode = new DeepAssignmentNode(expr, st, cursor - st, fields, opLookup(op), t, pCtx);
                                } else if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                                    return lastNode = new IndexedOperativeAssign(expr, st, cursor - st, opLookup(op), idx, fields, pCtx);
                                } else {
                                    return lastNode = new OperativeAssign(name, expr, st, cursor - st, opLookup(op), fields, pCtx);
                                }
                            }
                            break CaptureLoop;
                        case '<':
                            if ((lookAhead() == '<' && lookAhead(2) == '=')) {
                                name = new String(expr, st, trimLeft(cursor) - st);
                                st = cursor += 3;
                                captureToEOS();
                                if (union) {
                                    return lastNode = new DeepAssignmentNode(expr, st, cursor - st, fields, BW_SHIFT_LEFT, t, pCtx);
                                } else if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                                    return lastNode = new IndexedOperativeAssign(expr, st, cursor - st, BW_SHIFT_LEFT, idx, fields, pCtx);
                                } else {
                                    return lastNode = new OperativeAssign(name, expr, st, cursor - st, BW_SHIFT_LEFT, fields, pCtx);
                                }
                            }
                            break CaptureLoop;
                        case '>':
                            if (lookAhead() == '>') {
                                if (lookAhead(2) == '=') {
                                    name = new String(expr, st, trimLeft(cursor) - st);
                                    st = cursor += 3;
                                    captureToEOS();
                                    if (union) {
                                        return lastNode = new DeepAssignmentNode(expr, st, cursor - st, fields, BW_SHIFT_RIGHT, t, pCtx);
                                    } else if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                                        return lastNode = new IndexedOperativeAssign(expr, st, cursor - st, BW_SHIFT_RIGHT, idx, fields, pCtx);
                                    } else {
                                        return lastNode = new OperativeAssign(name, expr, st, cursor - st, BW_SHIFT_RIGHT, fields, pCtx);
                                    }
                                } else if ((lookAhead(2) == '>' && lookAhead(3) == '=')) {
                                    name = new String(expr, st, trimLeft(cursor) - st);
                                    st = cursor += 4;
                                    captureToEOS();
                                    if (union) {
                                        return lastNode = new DeepAssignmentNode(expr, st, cursor - st, fields, BW_USHIFT_RIGHT, t, pCtx);
                                    } else if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                                        return lastNode = new IndexedOperativeAssign(expr, st, cursor - st, BW_USHIFT_RIGHT, idx, fields, pCtx);
                                    } else {
                                        return lastNode = new OperativeAssign(name, expr, st, cursor - st, BW_USHIFT_RIGHT, fields, pCtx);
                                    }
                                }
                            }
                            break CaptureLoop;
                        case '(':
                            cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '(', pCtx) + 1;
                            continue;
                        case '[':
                            cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '[', pCtx) + 1;
                            continue;
                        case '{':
                            if (!union)
                                break CaptureLoop;
                            cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '{', pCtx) + 1;
                            continue;
                        case '~':
                            if (lookAhead() == '=') {
                                // tmp = subArray(start, trimLeft(cursor));
                                tmpStart = st;
                                int tmpOffset = cursor - st;
                                st = cursor += 2;
                                captureToEOT();
                                return lastNode = new RegExMatch(expr, tmpStart, tmpOffset, fields, st, cursor - st, pCtx);
                            }
                            break CaptureLoop;
                        case '=':
                            if (lookAhead() == '+') {
                                name = new String(expr, st, trimLeft(cursor) - st);
                                st = cursor += 2;
                                if (!isNextIdentifierOrLiteral()) {
                                    throw new CompileException("unexpected symbol '" + expr[cursor] + "'", expr, st);
                                }
                                captureToEOS();
                                if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                                    return lastNode = new IndexedOperativeAssign(expr, st, cursor - st, ADD, idx, fields, pCtx);
                                } else {
                                    return lastNode = new OperativeAssign(name, expr, st, cursor - st, ADD, fields, pCtx);
                                }
                            } else if (lookAhead() == '-') {
                                name = new String(expr, st, trimLeft(cursor) - st);
                                st = cursor += 2;
                                if (!isNextIdentifierOrLiteral()) {
                                    throw new CompileException("unexpected symbol '" + expr[cursor] + "'", expr, st);
                                }
                                captureToEOS();
                                if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                                    return lastNode = new IndexedOperativeAssign(expr, st, cursor - st, SUB, idx, fields, pCtx);
                                } else {
                                    return lastNode = new OperativeAssign(name, expr, st, cursor - st, SUB, fields, pCtx);
                                }
                            }
                            if (greedy && lookAhead() != '=') {
                                cursor++;
                                if (union) {
                                    captureToEOS();
                                    return lastNode = new DeepAssignmentNode(expr, st, cursor - st, fields | ASTNode.ASSIGN, pCtx);
                                } else if (lastWasIdentifier) {
                                    return procTypedNode(false);
                                } else if (pCtx != null && ((idx = pCtx.variableIndexOf(t)) != -1 && (pCtx.isIndexAllocation()))) {
                                    captureToEOS();
                                    IndexedAssignmentNode ian = new IndexedAssignmentNode(expr, st = trimRight(st), trimLeft(cursor) - st, ASTNode.ASSIGN, idx, pCtx);
                                    if (idx == -1) {
                                        pCtx.addIndexedInput(t = ian.getVarName());
                                        ian.setRegister(pCtx.variableIndexOf(t));
                                    }
                                    return lastNode = ian;
                                } else {
                                    captureToEOS();
                                    return lastNode = new AssignmentNode(expr, st, cursor - st, fields | ASTNode.ASSIGN, pCtx);
                                }
                            }
                            break CaptureLoop;
                        default:
                            if (cursor != end) {
                                if (isIdentifierPart(expr[cursor])) {
                                    if (!union) {
                                        break CaptureLoop;
                                    }
                                    cursor++;
                                    while (cursor != end && isIdentifierPart(expr[cursor])) cursor++;
                                } else if ((cursor + 1) != end && isIdentifierPart(expr[cursor + 1])) {
                                    break CaptureLoop;
                                } else {
                                    cursor++;
                                }
                            } else {
                                break CaptureLoop;
                            }
                    }
                }
                /**
                 * Produce the token.
                 */
                trimWhitespace();
                return createPropertyToken(st, cursor);
            } else {
                switch(expr[cursor]) {
                    case '.':
                        {
                            cursor++;
                            if (isDigit(expr[cursor])) {
                                capture = true;
                                continue;
                            }
                            expectNextChar_IW('{');
                            return lastNode = new ThisWithNode(expr, st, cursor - st - 1, cursor + 1, (cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '{', pCtx) + 1) - 3, fields, pCtx);
                        }
                    case '@':
                        {
                            st++;
                            captureToEOT();
                            if (pCtx == null || (pCtx.getInterceptors() == null || !pCtx.getInterceptors().containsKey(name = new String(expr, st, cursor - st)))) {
                                throw new CompileException("reference to undefined interceptor: " + new String(expr, st, cursor - st), expr, st);
                            }
                            return lastNode = new InterceptorWrapper(pCtx.getInterceptors().get(name), nextToken(), pCtx);
                        }
                    case '=':
                        return createOperator(expr, st, (cursor += 2));
                    case '-':
                        if (lookAhead() == '-') {
                            cursor += 2;
                            skipWhitespace();
                            st = cursor;
                            captureIdentifier();
                            name = new String(subArray(st, cursor));
                            if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                                return lastNode = new IndexedPreFixDecNode(idx, pCtx);
                            } else {
                                return lastNode = new PreFixDecNode(name, pCtx);
                            }
                        } else if ((cursor == start || (lastNode != null && (lastNode instanceof BooleanNode || lastNode.isOperator()))) && !isDigit(lookAhead())) {
                            cursor += 1;
                            captureToEOT();
                            return new Sign(expr, st, cursor - st, fields, pCtx);
                        } else if ((cursor != start && (lastNode != null && !(lastNode instanceof BooleanNode || lastNode.isOperator()))) || !isDigit(lookAhead())) {
                            return createOperator(expr, st, cursor++ + 1);
                        } else if ((cursor - 1) != start || (!isDigit(expr[cursor - 1])) && isDigit(lookAhead())) {
                            cursor++;
                            break;
                        } else {
                            throw new CompileException("not a statement", expr, st);
                        }
                    case '+':
                        if (lookAhead() == '+') {
                            cursor += 2;
                            skipWhitespace();
                            st = cursor;
                            captureIdentifier();
                            name = new String(subArray(st, cursor));
                            if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                                return lastNode = new IndexedPreFixIncNode(idx, pCtx);
                            } else {
                                return lastNode = new PreFixIncNode(name, pCtx);
                            }
                        }
                        return createOperator(expr, st, cursor++ + 1);
                    case '*':
                        if (lookAhead() == '*') {
                            cursor++;
                        }
                        return createOperator(expr, st, cursor++ + 1);
                    case ';':
                        cursor++;
                        lastWasIdentifier = false;
                        return lastNode = new EndOfStatement(pCtx);
                    case '?':
                        if (cursor == start) {
                            cursor++;
                            continue;
                        }
                    case '#':
                    case '/':
                    case ':':
                    case '^':
                    case '%':
                        {
                            return createOperator(expr, st, cursor++ + 1);
                        }
                    case '(':
                        {
                            cursor++;
                            boolean singleToken = true;
                            skipWhitespace();
                            for (brace = 1; cursor != end && brace != 0; cursor++) {
                                switch(expr[cursor]) {
                                    case '(':
                                        brace++;
                                        break;
                                    case ')':
                                        brace--;
                                        break;
                                    case '\'':
                                        cursor = captureStringLiteral('\'', expr, cursor, end);
                                        break;
                                    case '"':
                                        cursor = captureStringLiteral('"', expr, cursor, end);
                                        break;
                                    case 'i':
                                        if (brace == 1 && isWhitespace(lookBehind()) && lookAhead() == 'n' && isWhitespace(lookAhead(2))) {
                                            for (int level = brace; cursor != end; cursor++) {
                                                switch(expr[cursor]) {
                                                    case '(':
                                                        brace++;
                                                        break;
                                                    case ')':
                                                        if (--brace < level) {
                                                            cursor++;
                                                            if (tokenContinues()) {
                                                                lastNode = new Fold(expr, trimRight(st + 1), cursor - st - 2, fields, pCtx);
                                                                if (expr[st = cursor] == '.')
                                                                    st++;
                                                                captureToEOT();
                                                                return lastNode = new Union(expr, st = trimRight(st), cursor - st, fields, lastNode, pCtx);
                                                            } else {
                                                                return lastNode = new Fold(expr, trimRight(st + 1), cursor - st - 2, fields, pCtx);
                                                            }
                                                        }
                                                        break;
                                                    case '\'':
                                                        cursor = captureStringLiteral('\'', expr, cursor, end);
                                                        break;
                                                    case '"':
                                                        cursor = captureStringLiteral('\"', expr, cursor, end);
                                                        break;
                                                }
                                            }
                                            throw new CompileException("unterminated projection; closing parathesis required", expr, st);
                                        }
                                        break;
                                    default:
                                        if (expr[cursor] != '.') {
                                            switch(expr[cursor]) {
                                                case '[':
                                                case ']':
                                                    break;
                                                default:
                                                    if (!(isIdentifierPart(expr[cursor]) || expr[cursor] == '.')) {
                                                        singleToken = false;
                                                    }
                                            }
                                        }
                                }
                            }
                            if (brace != 0) {
                                throw new CompileException("unbalanced braces in expression: (" + brace + "):", expr, st);
                            }
                            tmpStart = -1;
                            if (singleToken) {
                                int _st;
                                TypeDescriptor tDescr = new TypeDescriptor(expr, _st = trimRight(st + 1), trimLeft(cursor - 1) - _st, fields);
                                Class cls;
                                try {
                                    if (tDescr.isClass() && (cls = getClassReference(pCtx, tDescr)) != null) {
                                        // lookahead to check if it could be a real cast
                                        boolean isCast = false;
                                        for (int i = cursor; i < expr.length; i++) {
                                            if (expr[i] == ' ' || expr[i] == '\t')
                                                continue;
                                            isCast = isIdentifierPart(expr[i]) || expr[i] == '\'' || expr[i] == '"' || expr[i] == '(';
                                            break;
                                        }
                                        if (isCast) {
                                            st = cursor;
                                            captureToEOT();
                                            return lastNode = new TypeCast(expr, st, cursor - st, cls, fields, pCtx);
                                        }
                                    }
                                } catch (ClassNotFoundException e) {
                                // fallthrough
                                }
                            }
                            if (tmpStart != -1) {
                                return handleUnion(handleSubstatement(new Substatement(expr, tmpStart, cursor - tmpStart, fields, pCtx)));
                            } else {
                                return handleUnion(handleSubstatement(new Substatement(expr, st = trimRight(st + 1), trimLeft(cursor - 1) - st, fields, pCtx)));
                            }
                        }
                    case '}':
                    case ']':
                    case ')':
                        {
                            throw new CompileException("unbalanced braces", expr, st);
                        }
                    case '>':
                        {
                            switch(expr[cursor + 1]) {
                                case '>':
                                    if (expr[cursor += 2] == '>')
                                        cursor++;
                                    return createOperator(expr, st, cursor);
                                case '=':
                                    return createOperator(expr, st, cursor += 2);
                                default:
                                    return createOperator(expr, st, ++cursor);
                            }
                        }
                    case '<':
                        {
                            if (expr[++cursor] == '<') {
                                if (expr[++cursor] == '<')
                                    cursor++;
                                return createOperator(expr, st, cursor);
                            } else if (expr[cursor] == '=') {
                                return createOperator(expr, st, ++cursor);
                            } else {
                                return createOperator(expr, st, cursor);
                            }
                        }
                    case '\'':
                    case '"':
                        lastNode = new LiteralNode(handleStringEscapes(subset(expr, st + 1, (cursor = captureStringLiteral(expr[cursor], expr, cursor, end)) - st - 1)), String.class, pCtx);
                        cursor++;
                        if (tokenContinues()) {
                            return lastNode = handleUnion(lastNode);
                        }
                        return lastNode;
                    case '&':
                        {
                            if (expr[cursor++ + 1] == '&') {
                                return createOperator(expr, st, ++cursor);
                            } else {
                                return createOperator(expr, st, cursor);
                            }
                        }
                    case '|':
                        {
                            if (expr[cursor++ + 1] == '|') {
                                return createOperator(expr, st, ++cursor);
                            } else {
                                return createOperator(expr, st, cursor);
                            }
                        }
                    case '~':
                        if ((cursor++ - 1 != 0 || !isIdentifierPart(lookBehind())) && isDigit(expr[cursor])) {
                            st = cursor;
                            captureToEOT();
                            return lastNode = new Invert(expr, st, cursor - st, fields, pCtx);
                        } else if (expr[cursor] == '(') {
                            st = cursor--;
                            captureToEOT();
                            return lastNode = new Invert(expr, st, cursor - st, fields, pCtx);
                        } else {
                            if (expr[cursor] == '=')
                                cursor++;
                            return createOperator(expr, st, cursor);
                        }
                    case '!':
                        {
                            ++cursor;
                            if (isNextIdentifier()) {
                                if (lastNode != null && !lastNode.isOperator()) {
                                    throw new CompileException("unexpected operator '!'", expr, st);
                                }
                                st = cursor;
                                captureToEOT();
                                if ("new".equals(name = new String(expr, st, cursor - st)) || "isdef".equals(name)) {
                                    captureToEOT();
                                    return lastNode = new Negation(expr, st, cursor - st, fields, pCtx);
                                } else {
                                    return lastNode = new Negation(expr, st, cursor - st, fields, pCtx);
                                }
                            } else if (expr[cursor] == '(') {
                                st = cursor--;
                                captureToEOT();
                                return lastNode = new Negation(expr, st, cursor - st, fields, pCtx);
                            } else if (expr[cursor] == '!') {
                                // just ignore a double negation
                                ++cursor;
                                return nextToken();
                            } else if (expr[cursor] != '=')
                                throw new CompileException("unexpected operator '!'", expr, st, null);
                            else {
                                return createOperator(expr, st, ++cursor);
                            }
                        }
                    case '[':
                    case '{':
                        cursor = balancedCaptureWithLineAccounting(expr, cursor, end, expr[cursor], pCtx) + 1;
                        if (tokenContinues()) {
                            lastNode = new InlineCollectionNode(expr, st, cursor - st, fields, pCtx);
                            st = cursor;
                            captureToEOT();
                            if (expr[st] == '.')
                                st++;
                            return lastNode = new Union(expr, st, cursor - st, fields, lastNode, pCtx);
                        } else {
                            return lastNode = new InlineCollectionNode(expr, st, cursor - st, fields, pCtx);
                        }
                    default:
                        cursor++;
                }
            }
        }
        if (st == cursor)
            return null;
        else
            return createPropertyToken(st, cursor);
    } catch (RedundantCodeException e) {
        return nextToken();
    } catch (NumberFormatException e) {
        throw new CompileException("badly formatted number: " + e.getMessage(), expr, st, e);
    } catch (StringIndexOutOfBoundsException e) {
        throw new CompileException("unexpected end of statement", expr, cursor, e);
    } catch (ArrayIndexOutOfBoundsException e) {
        throw new CompileException("unexpected end of statement", expr, cursor, e);
    } catch (CompileException e) {
        throw ErrorUtil.rewriteIfNeeded(e, expr, cursor);
    }
}
Also used : Fold(org.mvel2.ast.Fold) IndexedPreFixDecNode(org.mvel2.ast.IndexedPreFixDecNode) LineLabel(org.mvel2.ast.LineLabel) InterceptorWrapper(org.mvel2.ast.InterceptorWrapper) ThisWithNode(org.mvel2.ast.ThisWithNode) StaticImportNode(org.mvel2.ast.StaticImportNode) ImportNode(org.mvel2.ast.ImportNode) StaticImportNode(org.mvel2.ast.StaticImportNode) Invert(org.mvel2.ast.Invert) AssignmentNode(org.mvel2.ast.AssignmentNode) IndexedAssignmentNode(org.mvel2.ast.IndexedAssignmentNode) DeepAssignmentNode(org.mvel2.ast.DeepAssignmentNode) IndexedDeclTypedVarNode(org.mvel2.ast.IndexedDeclTypedVarNode) IndexedPreFixDecNode(org.mvel2.ast.IndexedPreFixDecNode) PreFixDecNode(org.mvel2.ast.PreFixDecNode) RedundantCodeException(org.mvel2.ast.RedundantCodeException) OperatorNode(org.mvel2.ast.OperatorNode) BooleanNode(org.mvel2.ast.BooleanNode) NewObjectPrototype(org.mvel2.ast.NewObjectPrototype) LiteralNode(org.mvel2.ast.LiteralNode) TypeDescriptor(org.mvel2.ast.TypeDescriptor) NewObjectNode(org.mvel2.ast.NewObjectNode) IndexedOperativeAssign(org.mvel2.ast.IndexedOperativeAssign) TypeCast(org.mvel2.ast.TypeCast) IndexedPreFixIncNode(org.mvel2.ast.IndexedPreFixIncNode) Substatement(org.mvel2.ast.Substatement) IndexedPostFixIncNode(org.mvel2.ast.IndexedPostFixIncNode) PostFixIncNode(org.mvel2.ast.PostFixIncNode) IndexedPostFixDecNode(org.mvel2.ast.IndexedPostFixDecNode) Negation(org.mvel2.ast.Negation) InlineCollectionNode(org.mvel2.ast.InlineCollectionNode) IndexedPostFixIncNode(org.mvel2.ast.IndexedPostFixIncNode) OperativeAssign(org.mvel2.ast.OperativeAssign) IndexedOperativeAssign(org.mvel2.ast.IndexedOperativeAssign) Union(org.mvel2.ast.Union) NewPrototypeNode(org.mvel2.ast.NewPrototypeNode) CompileException(org.mvel2.CompileException) IsDef(org.mvel2.ast.IsDef) PreFixIncNode(org.mvel2.ast.PreFixIncNode) IndexedPreFixIncNode(org.mvel2.ast.IndexedPreFixIncNode) RegExMatch(org.mvel2.ast.RegExMatch) EndOfStatement(org.mvel2.ast.EndOfStatement) DeepAssignmentNode(org.mvel2.ast.DeepAssignmentNode) ReturnNode(org.mvel2.ast.ReturnNode) IndexedAssignmentNode(org.mvel2.ast.IndexedAssignmentNode) IndexedPostFixDecNode(org.mvel2.ast.IndexedPostFixDecNode) PostFixDecNode(org.mvel2.ast.PostFixDecNode) IndexedDeclTypedVarNode(org.mvel2.ast.IndexedDeclTypedVarNode) DeclTypedVarNode(org.mvel2.ast.DeclTypedVarNode) AssertNode(org.mvel2.ast.AssertNode) Sign(org.mvel2.ast.Sign)

Example 64 with CompileException

use of org.mule.mvel2.CompileException in project mvel by mvel.

the class AbstractParser method _captureBlock.

private ASTNode _captureBlock(ASTNode node, final char[] expr, boolean cond, int type) {
    skipWhitespace();
    int startCond = 0;
    int endCond = 0;
    int blockStart;
    int blockEnd;
    String name;
    /**
     * Functions are a special case we handle differently from the rest of block parsing
     */
    switch(type) {
        case FUNCTION:
            {
                int st = cursor;
                captureToNextTokenJunction();
                if (cursor == end) {
                    throw new CompileException("unexpected end of statement", expr, st);
                }
                /**
                 * Check to see if the name is legal.
                 */
                if (isReservedWord(name = createStringTrimmed(expr, st, cursor - st)) || isNotValidNameorLabel(name))
                    throw new CompileException("illegal function name or use of reserved word", expr, cursor);
                FunctionParser parser = new FunctionParser(name, cursor, end - cursor, expr, fields, pCtx, splitAccumulator);
                Function function = parser.parse();
                cursor = parser.getCursor();
                return lastNode = function;
            }
        case PROTO:
            {
                if (ProtoParser.isUnresolvedWaiting()) {
                    ProtoParser.checkForPossibleUnresolvedViolations(expr, cursor, pCtx);
                }
                int st = cursor;
                captureToNextTokenJunction();
                if (isReservedWord(name = createStringTrimmed(expr, st, cursor - st)) || isNotValidNameorLabel(name))
                    throw new CompileException("illegal prototype name or use of reserved word", expr, cursor);
                if (expr[cursor = nextNonBlank()] != '{') {
                    throw new CompileException("expected '{' but found: " + expr[cursor], expr, cursor);
                }
                cursor = balancedCaptureWithLineAccounting(expr, st = cursor + 1, end, '{', pCtx);
                ProtoParser parser = new ProtoParser(expr, st, cursor, name, pCtx, fields, splitAccumulator);
                Proto proto = parser.parse();
                pCtx.addImport(proto);
                proto.setCursorPosition(st, cursor);
                cursor = parser.getCursor();
                ProtoParser.notifyForLateResolution(proto);
                return lastNode = proto;
            }
        case STACKLANG:
            {
                if (expr[cursor = nextNonBlank()] != '{') {
                    throw new CompileException("expected '{' but found: " + expr[cursor], expr, cursor);
                }
                int st;
                cursor = balancedCaptureWithLineAccounting(expr, st = cursor + 1, end, '{', pCtx);
                Stacklang stacklang = new Stacklang(expr, st, cursor - st, fields, pCtx);
                cursor++;
                return lastNode = stacklang;
            }
        default:
            if (cond) {
                if (expr[cursor] != '(') {
                    throw new CompileException("expected '(' but encountered: " + expr[cursor], expr, cursor);
                }
                /**
                 * This block is an: IF, FOREACH or WHILE node.
                 */
                endCond = cursor = balancedCaptureWithLineAccounting(expr, startCond = cursor, end, '(', pCtx);
                startCond++;
                cursor++;
            }
    }
    skipWhitespace();
    if (cursor >= end) {
        throw new CompileException("unexpected end of statement", expr, end);
    } else if (expr[cursor] == '{') {
        blockEnd = cursor = balancedCaptureWithLineAccounting(expr, blockStart = cursor, end, '{', pCtx);
    } else {
        blockStart = cursor - 1;
        captureToEOSorEOL();
        blockEnd = cursor + 1;
    }
    if (type == ASTNode.BLOCK_IF) {
        IfNode ifNode = (IfNode) node;
        if (node != null) {
            if (!cond) {
                return ifNode.setElseBlock(expr, st = trimRight(blockStart + 1), trimLeft(blockEnd) - st, pCtx);
            } else {
                return ifNode.setElseIf((IfNode) createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd), type));
            }
        } else {
            return createBlockToken(startCond, endCond, blockStart + 1, blockEnd, type);
        }
    } else if (type == ASTNode.BLOCK_DO) {
        cursor++;
        skipWhitespace();
        st = cursor;
        captureToNextTokenJunction();
        if ("while".equals(name = new String(expr, st, cursor - st))) {
            skipWhitespace();
            startCond = cursor + 1;
            endCond = cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '(', pCtx);
            return createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd), type);
        } else if ("until".equals(name)) {
            skipWhitespace();
            startCond = cursor + 1;
            endCond = cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '(', pCtx);
            return createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd), ASTNode.BLOCK_DO_UNTIL);
        } else {
            throw new CompileException("expected 'while' or 'until' but encountered: " + name, expr, cursor);
        }
    } else // DON"T REMOVE THIS COMMENT!
    // else if (isFlag(ASTNode.BLOCK_FOREACH) || isFlag(ASTNode.BLOCK_WITH)) {
    {
        return createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd), type);
    }
}
Also used : FunctionParser(org.mvel2.util.FunctionParser) Function(org.mvel2.ast.Function) ProtoParser(org.mvel2.util.ProtoParser) Proto(org.mvel2.ast.Proto) CompileException(org.mvel2.CompileException) IfNode(org.mvel2.ast.IfNode) Stacklang(org.mvel2.ast.Stacklang)

Example 65 with CompileException

use of org.mule.mvel2.CompileException in project mvel by mvel.

the class ExpressionCompiler method _compile.

/**
 * Initiate an in-context compileShared.  This method should really only be called by the internal API.
 *
 * @return compiled expression object
 */
public CompiledExpression _compile() {
    ASTNode tk;
    ASTNode tkOp;
    ASTNode tkOp2;
    ASTNode tkLA;
    ASTNode tkLA2;
    int op, lastOp = -1;
    cursor = start;
    ASTLinkedList astBuild = new ASTLinkedList();
    stk = new ExecutionStack();
    dStack = new ExecutionStack();
    compileMode = true;
    boolean firstLA;
    try {
        if (verifying) {
            pCtx.initializeTables();
        }
        fields |= COMPILE_IMMEDIATE;
        while ((tk = nextToken()) != null) {
            /**
             * If this is a debug symbol, just add it and continue.
             */
            if (tk.fields == -1) {
                astBuild.addTokenNode(tk);
                continue;
            }
            /**
             * Record the type of the current node..
             */
            returnType = tk.getEgressType();
            if (tk instanceof Substatement) {
                String key = new String(expr, tk.getStart(), tk.getOffset());
                Map<String, CompiledExpression> cec = pCtx.getCompiledExpressionCache();
                Map<String, Class> rtc = pCtx.getReturnTypeCache();
                CompiledExpression compiled = cec.get(key);
                Class rt = rtc.get(key);
                if (compiled == null) {
                    ExpressionCompiler subCompiler = new ExpressionCompiler(expr, tk.getStart(), tk.getOffset(), pCtx);
                    compiled = subCompiler._compile();
                    rt = subCompiler.getReturnType();
                    cec.put(key, compiled);
                    rtc.put(key, rt);
                }
                tk.setAccessor(compiled);
                returnType = rt;
            }
            /**
             * This kludge of code is to handle compileShared-time literal reduction.  We need to avoid
             * reducing for certain literals like, 'this', ternary and ternary else.
             */
            if (!verifyOnly && tk.isLiteral()) {
                if (literalOnly == -1)
                    literalOnly = 1;
                if ((tkOp = nextTokenSkipSymbols()) != null && tkOp.isOperator() && !tkOp.isOperator(Operator.TERNARY) && !tkOp.isOperator(Operator.TERNARY_ELSE)) {
                    /**
                     * If the next token is ALSO a literal, then we have a candidate for a compileShared-time literal
                     * reduction.
                     */
                    if ((tkLA = nextTokenSkipSymbols()) != null && tkLA.isLiteral() && tkOp.getOperator() < 34 && ((lastOp == -1 || (lastOp < PTABLE.length && PTABLE[lastOp] < PTABLE[tkOp.getOperator()])))) {
                        stk.push(tk.getLiteralValue(), tkLA.getLiteralValue(), op = tkOp.getOperator());
                        /**
                         * Reduce the token now.
                         */
                        if (isArithmeticOperator(op)) {
                            if (!compileReduce(op, astBuild))
                                continue;
                        } else {
                            reduce();
                        }
                        firstLA = true;
                        /**
                         * Now we need to check to see if this is a continuing reduction.
                         */
                        while ((tkOp2 = nextTokenSkipSymbols()) != null) {
                            if (isBooleanOperator(tkOp2.getOperator())) {
                                astBuild.addTokenNode(new LiteralNode(stk.pop(), pCtx), verify(pCtx, tkOp2));
                                break;
                            } else if ((tkLA2 = nextTokenSkipSymbols()) != null) {
                                if (tkLA2.isLiteral()) {
                                    stk.push(tkLA2.getLiteralValue(), op = tkOp2.getOperator());
                                    if (isArithmeticOperator(op)) {
                                        compileReduce(op, astBuild);
                                    } else {
                                        reduce();
                                    }
                                } else {
                                    /**
                                     * A reducable line of literals has ended.  We must now terminate here and
                                     * leave the rest to be determined at runtime.
                                     */
                                    if (!stk.isEmpty()) {
                                        astBuild.addTokenNode(new LiteralNode(getStackValueResult(), pCtx));
                                    }
                                    astBuild.addTokenNode(new OperatorNode(tkOp2.getOperator(), expr, st, pCtx), verify(pCtx, tkLA2));
                                    break;
                                }
                                firstLA = false;
                                literalOnly = 0;
                            } else {
                                if (firstLA) {
                                    /**
                                     * There are more tokens, but we can't reduce anymore.  So
                                     * we create a reduced token for what we've got.
                                     */
                                    astBuild.addTokenNode(new LiteralNode(getStackValueResult(), pCtx));
                                } else {
                                    /**
                                     * We have reduced additional tokens, but we can't reduce
                                     * anymore.
                                     */
                                    astBuild.addTokenNode(new LiteralNode(getStackValueResult(), pCtx), tkOp2);
                                    if (tkLA2 != null)
                                        astBuild.addTokenNode(verify(pCtx, tkLA2));
                                }
                                break;
                            }
                        }
                        /**
                         * If there are no more tokens left to parse, we check to see if
                         * we've been doing any reducing, and if so we create the token
                         * now.
                         */
                        if (!stk.isEmpty())
                            astBuild.addTokenNode(new LiteralNode(getStackValueResult(), pCtx));
                        continue;
                    } else {
                        astBuild.addTokenNode(verify(pCtx, tk), verify(pCtx, tkOp));
                        if (tkLA != null)
                            astBuild.addTokenNode(verify(pCtx, tkLA));
                        continue;
                    }
                } else if (tkOp != null && !tkOp.isOperator() && !(tk.getLiteralValue() instanceof Class)) {
                    throw new CompileException("unexpected token: " + tkOp.getName(), expr, tkOp.getStart());
                } else {
                    literalOnly = 0;
                    astBuild.addTokenNode(verify(pCtx, tk));
                    if (tkOp != null)
                        astBuild.addTokenNode(verify(pCtx, tkOp));
                    continue;
                }
            } else {
                if (tk.isOperator()) {
                    lastOp = tk.getOperator();
                } else {
                    literalOnly = 0;
                }
            }
            astBuild.addTokenNode(verify(pCtx, tk));
        }
        astBuild.finish();
        if (verifying && !verifyOnly) {
            pCtx.processTables();
        }
        if (!stk.isEmpty()) {
            throw new CompileException("COMPILE ERROR: non-empty stack after compileShared.", expr, cursor);
        }
        if (!verifyOnly) {
            try {
                return new CompiledExpression(finalizePayload(astBuild, secondPassOptimization, pCtx), pCtx.getSourceFile(), returnType, pCtx.getParserConfiguration(), literalOnly == 1);
            } catch (RuntimeException e) {
                throw new CompileException(e.getMessage(), expr, st, e);
            }
        } else {
            try {
                returnType = CompilerTools.getReturnType(astBuild, pCtx.isStrongTyping());
            } catch (RuntimeException e) {
                throw new CompileException(e.getMessage(), expr, st, e);
            }
            return null;
        }
    } catch (NullPointerException e) {
        throw new CompileException("not a statement, or badly formed structure", expr, st, e);
    } catch (CompileException e) {
        throw ErrorUtil.rewriteIfNeeded(e, expr, st);
    } catch (Throwable e) {
        if (e instanceof RuntimeException)
            throw (RuntimeException) e;
        else {
            throw new CompileException(e.getMessage(), expr, st, e);
        }
    }
}
Also used : ExecutionStack(org.mvel2.util.ExecutionStack) OperatorNode(org.mvel2.ast.OperatorNode) LiteralNode(org.mvel2.ast.LiteralNode) ASTNode(org.mvel2.ast.ASTNode) ASTLinkedList(org.mvel2.util.ASTLinkedList) CompileException(org.mvel2.CompileException) Substatement(org.mvel2.ast.Substatement)

Aggregations

CompileException (org.mvel2.CompileException)83 ParserContext (org.mvel2.ParserContext)14 Map (java.util.Map)13 ExecutableStatement (org.mvel2.compiler.ExecutableStatement)13 PropertyAccessException (org.mvel2.PropertyAccessException)12 InvocationTargetException (java.lang.reflect.InvocationTargetException)11 List (java.util.List)11 ArrayList (java.util.ArrayList)10 IOException (java.io.IOException)9 Method (java.lang.reflect.Method)7 TypeDescriptor (org.mvel2.ast.TypeDescriptor)7 Field (java.lang.reflect.Field)6 HashMap (java.util.HashMap)6 EndOfStatement (org.mvel2.ast.EndOfStatement)6 Proto (org.mvel2.ast.Proto)6 Constructor (java.lang.reflect.Constructor)5 Member (java.lang.reflect.Member)5 ASTNode (org.mvel2.ast.ASTNode)5 LiteralNode (org.mvel2.ast.LiteralNode)5 Collection (java.util.Collection)4