Search in sources :

Example 16 with CompileException

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

the class AbstractParser method createPropertyToken.

/**
 * Generate a property token
 *
 * @param st  the start offset
 * @param end the end offset
 * @return an ast node
 */
private ASTNode createPropertyToken(int st, int end) {
    String tmp;
    if (isPropertyOnly(expr, st, end)) {
        if (pCtx != null && pCtx.hasImports()) {
            int find;
            if ((find = findFirst('.', st, end - st, expr)) != -1) {
                String iStr = new String(expr, st, find - st);
                if (pCtx.hasImport(iStr)) {
                    lastWasIdentifier = true;
                    return lastNode = new LiteralDeepPropertyNode(expr, find + 1, end - find - 1, fields, pCtx.getImport(iStr), pCtx);
                }
            } else {
                if (pCtx.hasImport(tmp = new String(expr, st, cursor - st))) {
                    lastWasIdentifier = true;
                    return lastNode = new LiteralNode(pCtx.getStaticOrClassImport(tmp), pCtx);
                }
            }
        }
        if (LITERALS.containsKey(tmp = new String(expr, st, end - st))) {
            lastWasIdentifier = true;
            return lastNode = new LiteralNode(LITERALS.get(tmp), pCtx);
        } else if (OPERATORS.containsKey(tmp)) {
            lastWasIdentifier = false;
            return lastNode = new OperatorNode(OPERATORS.get(tmp), expr, st, pCtx);
        } else if (lastWasIdentifier) {
            return procTypedNode(true);
        }
    }
    if (pCtx != null && isArrayType(expr, st, end)) {
        if (pCtx.hasImport(new String(expr, st, cursor - st - 2))) {
            lastWasIdentifier = true;
            TypeDescriptor typeDescriptor = new TypeDescriptor(expr, st, cursor - st, fields);
            try {
                return lastNode = new LiteralNode(typeDescriptor.getClassReference(pCtx), pCtx);
            } catch (ClassNotFoundException e) {
                throw new CompileException("could not resolve class: " + typeDescriptor.getClassName(), expr, st);
            }
        }
    }
    lastWasIdentifier = true;
    return lastNode = new ASTNode(expr, trimRight(st), trimLeft(end) - st, fields, pCtx);
}
Also used : LiteralNode(org.mvel2.ast.LiteralNode) LiteralDeepPropertyNode(org.mvel2.ast.LiteralDeepPropertyNode) TypeDescriptor(org.mvel2.ast.TypeDescriptor) ASTNode(org.mvel2.ast.ASTNode) CompileException(org.mvel2.CompileException) OperatorNode(org.mvel2.ast.OperatorNode)

Example 17 with CompileException

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

the class AbstractParser method reduce.

/**
 * This method is called when we reach the point where we must subEval a trinary operation in the expression.
 * (ie. val1 op val2).  This is not the same as a binary operation, although binary operations would appear
 * to have 3 structures as well.  A binary structure (or also a junction in the expression) compares the
 * current state against 2 downrange structures (usually an op and a val).
 */
protected void reduce() {
    Object v1, v2;
    int operator;
    try {
        switch(operator = (Integer) stk.pop()) {
            case ADD:
            case SUB:
            case DIV:
            case MULT:
            case MOD:
            case EQUAL:
            case NEQUAL:
            case GTHAN:
            case LTHAN:
            case GETHAN:
            case LETHAN:
            case POWER:
                stk.op(operator);
                break;
            case AND:
                v1 = stk.pop();
                stk.push(((Boolean) stk.pop()) && ((Boolean) v1));
                break;
            case OR:
                v1 = stk.pop();
                stk.push(((Boolean) stk.pop()) || ((Boolean) v1));
                break;
            case CHOR:
                v1 = stk.pop();
                if (!isEmpty(v2 = stk.pop()) || !isEmpty(v1)) {
                    stk.clear();
                    stk.push(!isEmpty(v2) ? v2 : v1);
                    return;
                } else
                    stk.push(null);
                break;
            case REGEX:
                stk.push(java.util.regex.Pattern.compile(java.lang.String.valueOf(stk.pop())).matcher(java.lang.String.valueOf(stk.pop())).matches());
                break;
            case INSTANCEOF:
                stk.push(((Class) stk.pop()).isInstance(stk.pop()));
                break;
            case CONVERTABLE_TO:
                stk.push(org.mvel2.DataConversion.canConvert(stk.peek2().getClass(), (Class) stk.pop2()));
                break;
            case CONTAINS:
                stk.push(containsCheck(stk.peek2(), stk.pop2()));
                break;
            case SOUNDEX:
                stk.push(soundex(java.lang.String.valueOf(stk.pop())).equals(soundex(java.lang.String.valueOf(stk.pop()))));
                break;
            case SIMILARITY:
                stk.push(similarity(java.lang.String.valueOf(stk.pop()), java.lang.String.valueOf(stk.pop())));
                break;
            default:
                reduceNumeric(operator);
        }
    } catch (ClassCastException e) {
        throw new CompileException("syntax error or incompatable types", expr, st, e);
    } catch (ArithmeticException e) {
        throw new CompileException("arithmetic error: " + e.getMessage(), expr, st, e);
    } catch (Exception e) {
        throw new CompileException("failed to subEval expression", expr, st, e);
    }
}
Also used : CompileException(org.mvel2.CompileException) CompileException(org.mvel2.CompileException) RedundantCodeException(org.mvel2.ast.RedundantCodeException)

Example 18 with CompileException

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

the class ExpressionCompiler method verify.

protected ASTNode verify(ParserContext pCtx, ASTNode tk) {
    if (tk.isOperator() && (tk.getOperator().equals(Operator.AND) || tk.getOperator().equals(Operator.OR))) {
        secondPassOptimization = true;
    }
    if (tk.isDiscard() || tk.isOperator()) {
        return tk;
    } else if (tk.isLiteral()) {
        /**
         * Convert literal values from the default ASTNode to the more-efficient LiteralNode.
         */
        if ((fields & COMPILE_IMMEDIATE) != 0 && tk.getClass() == ASTNode.class) {
            return new LiteralNode(tk.getLiteralValue(), pCtx);
        } else {
            return tk;
        }
    }
    if (verifying) {
        if (tk.isIdentifier()) {
            PropertyVerifier propVerifier = new PropertyVerifier(expr, tk.getStart(), tk.getOffset(), pCtx);
            if (tk instanceof Union) {
                propVerifier.setCtx(((Union) tk).getLeftEgressType());
                tk.setEgressType(returnType = propVerifier.analyze());
            } else {
                tk.setEgressType(returnType = propVerifier.analyze());
                if (propVerifier.isFqcn()) {
                    tk.setAsFQCNReference();
                }
                if (propVerifier.isClassLiteral()) {
                    return new LiteralNode(returnType, pCtx);
                }
                if (propVerifier.isInput()) {
                    pCtx.addInput(tk.getAbsoluteName(), propVerifier.isDeepProperty() ? Object.class : returnType);
                }
                if (!propVerifier.isMethodCall() && !returnType.isEnum() && !pCtx.isOptimizerNotified() && pCtx.isStrongTyping() && !pCtx.isVariableVisible(tk.getAbsoluteName()) && !tk.isFQCN()) {
                    throw new CompileException("no such identifier: " + tk.getAbsoluteName(), expr, tk.getStart());
                }
            }
        } else if (tk.isAssignment()) {
            Assignment a = (Assignment) tk;
            if (a.getAssignmentVar() != null) {
                // pCtx.makeVisible(a.getAssignmentVar());
                PropertyVerifier propVerifier = new PropertyVerifier(a.getAssignmentVar(), pCtx);
                tk.setEgressType(returnType = propVerifier.analyze());
                if (!a.isNewDeclaration() && propVerifier.isResolvedExternally()) {
                    pCtx.addInput(tk.getAbsoluteName(), returnType);
                }
                ExecutableStatement c = (ExecutableStatement) subCompileExpression(expr, tk.getStart(), tk.getOffset(), pCtx);
                if (pCtx.isStrictTypeEnforcement()) {
                    /**
                     * If we're using strict type enforcement, we need to see if this coercion can be done now,
                     * or fail epicly.
                     */
                    if (!returnType.isAssignableFrom(c.getKnownEgressType()) && c.isLiteralOnly()) {
                        if (canConvert(c.getKnownEgressType(), returnType)) {
                            /**
                             * We convert the literal to the proper type.
                             */
                            try {
                                a.setValueStatement(new ExecutableLiteral(convert(c.getValue(null, null), returnType)));
                                return tk;
                            } catch (Exception e) {
                            // fall through.
                            }
                        } else if (returnType.isPrimitive() && unboxPrimitive(c.getKnownEgressType()).equals(returnType)) {
                            /**
                             * We ignore boxed primitive cases, since MVEL does not recognize primitives.
                             */
                            return tk;
                        }
                        throw new CompileException("cannot assign type " + c.getKnownEgressType().getName() + " to " + returnType.getName(), expr, st);
                    }
                }
            }
        } else if (tk instanceof NewObjectNode) {
            // this is a bit of a hack for now.
            NewObjectNode n = (NewObjectNode) tk;
            List<char[]> parms = ParseTools.parseMethodOrConstructor(tk.getNameAsArray());
            if (parms != null) {
                for (char[] p : parms) {
                    MVEL.analyze(p, pCtx);
                }
            }
        }
        returnType = tk.getEgressType();
    }
    if (!tk.isLiteral() && tk.getClass() == ASTNode.class && (tk.getFields() & ASTNode.ARRAY_TYPE_LITERAL) == 0) {
        if (pCtx.isStrongTyping())
            tk.strongTyping();
        tk.storePctx();
        tk.storeInLiteralRegister(pCtx);
    }
    return tk;
}
Also used : Assignment(org.mvel2.ast.Assignment) LiteralNode(org.mvel2.ast.LiteralNode) NewObjectNode(org.mvel2.ast.NewObjectNode) CompileException(org.mvel2.CompileException) Union(org.mvel2.ast.Union) CompileException(org.mvel2.CompileException)

Example 19 with CompileException

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

the class PropertyVerifier method getCollectionProperty.

/**
 * Process collection property
 *
 * @param ctx      - the ingress type
 * @param property - the property component
 * @return known egress type
 */
private Class getCollectionProperty(Class ctx, String property) {
    if (first) {
        if (pCtx.hasVarOrInput(property)) {
            ctx = getSubComponentType(pCtx.getVarOrInputType(property));
        } else if (pCtx.hasImport(property)) {
            resolvedExternally = false;
            ctx = getSubComponentType(pCtx.getImport(property));
        } else {
            ctx = Object.class;
        }
    }
    if (pCtx.isStrictTypeEnforcement()) {
        if (Map.class.isAssignableFrom(property.length() != 0 ? ctx = getBeanProperty(ctx, property) : ctx)) {
            ctx = type2Class(pCtx.getLastTypeParameters() != null && pCtx.getLastTypeParameters().length != 0 ? pCtx.getLastTypeParameters()[1] : Object.class);
        } else if (Collection.class.isAssignableFrom(ctx)) {
            ctx = pCtx.getLastTypeParameters() == null || pCtx.getLastTypeParameters().length == 0 ? Object.class : type2Class(pCtx.getLastTypeParameters()[0]);
        } else if (ctx.isArray()) {
            ctx = ctx.getComponentType();
        } else if (pCtx.isStrongTyping()) {
            throw new CompileException("unknown collection type: " + ctx + "; property=" + property, expr, start);
        }
    } else {
        ctx = Object.class;
    }
    ++cursor;
    skipWhitespace();
    int start = cursor;
    if (scanTo(']')) {
        addFatalError("unterminated [ in token");
    }
    MVEL.analysisCompile(new String(expr, start, cursor - start), pCtx);
    ++cursor;
    return ctx;
}
Also used : Collection(java.util.Collection) CompileException(org.mvel2.CompileException)

Example 20 with CompileException

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

the class PropertyVerifier method getMethod.

/**
 * Process method
 *
 * @param ctx  - the ingress type
 * @param name - the property component
 * @return known egress type.
 */
private Class getMethod(Class ctx, String name) {
    int st = cursor;
    /**
     * Check to see if this is the first element in the statement.
     */
    if (first) {
        first = false;
        methodCall = true;
        /**
         * It's the first element in the statement, therefore we check to see if there is a static import of a
         * native Java method or an MVEL function.
         */
        if (pCtx.hasImport(name)) {
            Method m = pCtx.getStaticImport(name).getMethod();
            /**
             * Replace the method parameters.
             */
            ctx = m.getDeclaringClass();
            name = m.getName();
        } else {
            Function f = pCtx.getFunction(name);
            if (f != null && f.getEgressType() != null) {
                resolvedExternally = false;
                f.checkArgumentCount(parseParameterList((((cursor = balancedCapture(expr, cursor, end, '(')) - st) > 1 ? ParseTools.subset(expr, st + 1, cursor - st - 1) : new char[0]), 0, -1).size());
                return f.getEgressType();
            } else if (pCtx.hasVarOrInput("this")) {
                if (pCtx.isStrictTypeEnforcement()) {
                    recordTypeParmsForProperty("this");
                }
                ctx = pCtx.getVarOrInputType("this");
                resolvedExternally = false;
            }
        }
    }
    /**
     * Get the arguments for the method.
     */
    String tk;
    if (cursor < end && expr[cursor] == '(' && ((cursor = balancedCapture(expr, cursor, end, '(')) - st) > 1) {
        tk = new String(expr, st + 1, cursor - st - 1);
    } else {
        tk = "";
    }
    cursor++;
    /**
     * Parse out the arguments list.
     */
    Class[] args;
    List<char[]> subtokens = parseParameterList(tk.toCharArray(), 0, -1);
    if (subtokens.size() == 0) {
        args = new Class[0];
        subtokens = Collections.emptyList();
    } else {
        // ParserContext subCtx = pCtx.createSubcontext();
        args = new Class[subtokens.size()];
        /**
         *  Subcompile all the arguments to determine their known types.
         */
        // ExpressionCompiler compiler;
        List<ErrorDetail> errors = pCtx.getErrorList().isEmpty() ? pCtx.getErrorList() : new ArrayList<ErrorDetail>(pCtx.getErrorList());
        CompileException rethrow = null;
        for (int i = 0; i < subtokens.size(); i++) {
            try {
                args[i] = MVEL.analyze(subtokens.get(i), pCtx);
                if ("null".equals(String.valueOf(subtokens.get(i)))) {
                    args[i] = NullType.class;
                }
            } catch (CompileException e) {
                rethrow = ErrorUtil.rewriteIfNeeded(e, expr, this.st);
            }
            if (errors.size() < pCtx.getErrorList().size()) {
                for (ErrorDetail detail : pCtx.getErrorList()) {
                    if (!errors.contains(detail)) {
                        detail.setExpr(expr);
                        detail.setCursor(new String(expr).substring(this.st).indexOf(new String(subtokens.get(i))) + this.st);
                        detail.setColumn(0);
                        detail.setLineNumber(0);
                        detail.calcRowAndColumn();
                    }
                }
            }
            if (rethrow != null) {
                throw rethrow;
            }
        }
    }
    /**
     * If the target object is an instance of java.lang.Class itself then do not
     * adjust the Class scope target.
     */
    Method m;
    if ((m = getBestCandidate(args, name, ctx, ctx.getMethods(), pCtx.isStrongTyping())) == null) {
        if ((m = getBestCandidate(args, name, ctx, ctx.getDeclaredMethods(), pCtx.isStrongTyping())) == null) {
            StringAppender errorBuild = new StringAppender();
            for (int i = 0; i < args.length; i++) {
                errorBuild.append(args[i] != null ? args[i].getName() : null);
                if (i < args.length - 1)
                    errorBuild.append(", ");
            }
            if (("size".equals(name) || "length".equals(name)) && args.length == 0 && ctx.isArray()) {
                return Integer.class;
            }
            if (pCtx.isStrictTypeEnforcement()) {
                throw new CompileException("unable to resolve method using strict-mode: " + ctx.getName() + "." + name + "(" + errorBuild.toString() + ")", expr, tkStart);
            }
            return Object.class;
        }
    }
    /**
     * If we're in strict mode, we look for generic type information.
     */
    if (pCtx.isStrictTypeEnforcement() && m.getGenericReturnType() != null) {
        Map<String, Class> typeArgs = new HashMap<String, Class>();
        Type[] gpt = m.getGenericParameterTypes();
        Class z;
        ParameterizedType pt;
        for (int i = 0; i < gpt.length; i++) {
            if (gpt[i] instanceof ParameterizedType) {
                pt = (ParameterizedType) gpt[i];
                if ((z = pCtx.getImport(new String(subtokens.get(i)))) != null) {
                    /**
                     * We record the value of the type parameter to our typeArgs Map.
                     */
                    if (pt.getRawType().equals(Class.class)) {
                        /**
                         * If this is an instance of Class, we deal with the special parameterization case.
                         */
                        typeArgs.put(pt.getActualTypeArguments()[0].toString(), z);
                    } else {
                        typeArgs.put(gpt[i].toString(), z);
                    }
                }
            }
        }
        if (pCtx.isStrictTypeEnforcement() && ctx.getTypeParameters().length != 0 && pCtx.getLastTypeParameters() != null && pCtx.getLastTypeParameters().length == ctx.getTypeParameters().length) {
            TypeVariable[] typeVariables = ctx.getTypeParameters();
            for (int i = 0; i < typeVariables.length; i++) {
                Type typeArg = pCtx.getLastTypeParameters()[i];
                typeArgs.put(typeVariables[i].getName(), typeArg instanceof Class ? type2Class(pCtx.getLastTypeParameters()[i]) : Object.class);
            }
        }
        /**
         * Get the return type argument
         */
        Type parametricReturnType = m.getGenericReturnType();
        String returnTypeArg = parametricReturnType.toString();
        // push return type parameters onto parser context, only if this is a parametric type
        if (parametricReturnType instanceof ParameterizedType) {
            pCtx.setLastTypeParameters(((ParameterizedType) parametricReturnType).getActualTypeArguments());
        }
        if (paramTypes != null && paramTypes.containsKey(returnTypeArg)) {
            /**
             * If the paramTypes Map contains the known type, return that type.
             */
            return type2Class(paramTypes.get(returnTypeArg));
        } else if (typeArgs.containsKey(returnTypeArg)) {
            /**
             * If the generic type was declared as part of the method, it will be in this
             * Map.
             */
            return typeArgs.get(returnTypeArg);
        }
    }
    if (!Modifier.isPublic(m.getModifiers()) && pCtx.isStrictTypeEnforcement()) {
        StringAppender errorBuild = new StringAppender();
        for (int i = 0; i < args.length; i++) {
            errorBuild.append(args[i] != null ? args[i].getName() : null);
            if (i < args.length - 1)
                errorBuild.append(", ");
        }
        String scope = Modifier.toString(m.getModifiers());
        if (scope.trim().equals(""))
            scope = "<package local>";
        addFatalError("the referenced method is not accessible: " + ctx.getName() + "." + name + "(" + errorBuild.toString() + ")" + " (scope: " + scope + "; required: public", this.tkStart);
    }
    return getReturnType(ctx, m);
}
Also used : HashMap(java.util.HashMap) Method(java.lang.reflect.Method) ErrorDetail(org.mvel2.ErrorDetail) ParameterizedType(java.lang.reflect.ParameterizedType) Function(org.mvel2.ast.Function) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) NullType(org.mvel2.util.NullType) TypeVariable(java.lang.reflect.TypeVariable) StringAppender(org.mvel2.util.StringAppender) CompileException(org.mvel2.CompileException)

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