Search in sources :

Example 36 with CompileException

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

the class ReflectiveAccessorOptimizer method getMethod.

/**
   * Find an appropriate method, execute it, and return it's response.
   *
   * @param ctx  -
   * @param name -
   * @return -
   * @throws Exception -
   */
@SuppressWarnings({ "unchecked" })
private Object getMethod(Object ctx, String name) throws Exception {
    int st = cursor;
    String tk = cursor != end && expr[cursor] == '(' && ((cursor = balancedCapture(expr, cursor, '(')) - st) > 1 ? new String(expr, st + 1, cursor - st - 1) : "";
    cursor++;
    Object[] args;
    Class[] argTypes;
    ExecutableStatement[] es;
    if (tk.length() == 0) {
        args = ParseTools.EMPTY_OBJ_ARR;
        argTypes = ParseTools.EMPTY_CLS_ARR;
        es = null;
    } else {
        List<char[]> subtokens = parseParameterList(tk.toCharArray(), 0, -1);
        es = new ExecutableStatement[subtokens.size()];
        args = new Object[subtokens.size()];
        argTypes = new Class[subtokens.size()];
        for (int i = 0; i < subtokens.size(); i++) {
            try {
                args[i] = (es[i] = (ExecutableStatement) subCompileExpression(subtokens.get(i), pCtx)).getValue(this.thisRef, thisRef, variableFactory);
            } catch (CompileException e) {
                throw ErrorUtil.rewriteIfNeeded(e, this.expr, this.start);
            }
            if (es[i].isExplicitCast())
                argTypes[i] = es[i].getKnownEgressType();
        }
        if (pCtx.isStrictTypeEnforcement()) {
            for (int i = 0; i < args.length; i++) {
                argTypes[i] = es[i].getKnownEgressType();
            }
        } else {
            for (int i = 0; i < args.length; i++) {
                if (argTypes[i] != null)
                    continue;
                if (es[i].getKnownEgressType() == Object.class) {
                    argTypes[i] = args[i] == null ? null : args[i].getClass();
                } else {
                    argTypes[i] = es[i].getKnownEgressType();
                }
            }
        }
    }
    if (first && variableFactory != null && variableFactory.isResolveable(name)) {
        Object ptr = variableFactory.getVariableResolver(name).getValue();
        if (ptr instanceof Method) {
            ctx = ((Method) ptr).getDeclaringClass();
            name = ((Method) ptr).getName();
        } else if (ptr instanceof MethodStub) {
            ctx = ((MethodStub) ptr).getClassReference();
            name = ((MethodStub) ptr).getMethodName();
        } else if (ptr instanceof Function) {
            Function func = (Function) ptr;
            if (!name.equals(func.getName())) {
                getBeanProperty(ctx, name);
                addAccessorNode(new DynamicFunctionAccessor(es));
            } else {
                addAccessorNode(new FunctionAccessor((Function) ptr, es));
            }
            return ((Function) ptr).call(ctx, thisRef, variableFactory, args);
        } else {
            throw new OptimizationFailure("attempt to optimize a method call for a reference that does not point to a method: " + name + " (reference is type: " + (ctx != null ? ctx.getClass().getName() : null) + ")");
        }
        first = false;
    }
    if (ctx == null) {
        throw new PropertyAccessException("null pointer or function not found: " + name, this.expr, this.start);
    }
    boolean classTarget = false;
    Class<?> cls = currType != null ? currType : ((classTarget = ctx instanceof Class) ? (Class<?>) ctx : ctx.getClass());
    currType = null;
    Method m;
    Class[] parameterTypes = null;
    if ((m = getBestCandidate(argTypes, name, cls, cls.getMethods(), false, classTarget)) != null) {
        parameterTypes = m.getParameterTypes();
    }
    if (m == null && classTarget) {
        /**
       * If we didn't find anything, maybe we're looking for the actual java.lang.Class methods.
       */
        if ((m = getBestCandidate(argTypes, name, cls, Class.class.getMethods(), false)) != null) {
            parameterTypes = m.getParameterTypes();
        }
    }
    if (m == null) {
        StringAppender errorBuild = new StringAppender();
        if ("size".equals(name) && args.length == 0 && cls.isArray()) {
            addAccessorNode(new ArrayLength());
            return getLength(ctx);
        }
        for (int i = 0; i < args.length; i++) {
            errorBuild.append(args[i] != null ? args[i].getClass().getName() : null);
            if (i < args.length - 1)
                errorBuild.append(", ");
        }
        throw new PropertyAccessException("unable to resolve method: " + cls.getName() + "." + name + "(" + errorBuild.toString() + ") [arglength=" + args.length + "]", this.expr, this.st);
    } else {
        if (es != null) {
            ExecutableStatement cExpr;
            for (int i = 0; i < es.length; i++) {
                cExpr = (ExecutableStatement) es[i];
                if (cExpr.getKnownIngressType() == null) {
                    cExpr.setKnownIngressType(parameterTypes[i]);
                    cExpr.computeTypeConversionRule();
                }
                if (!cExpr.isConvertableIngressEgress()) {
                    args[i] = convert(args[i], parameterTypes[i]);
                }
            }
        } else {
            /**
         * Coerce any types if required.
         */
            for (int i = 0; i < args.length; i++) args[i] = convert(args[i], parameterTypes[i]);
        }
        Object o = getWidenedTarget(m).invoke(ctx, args);
        if (hasNullMethodHandler()) {
            addAccessorNode(new MethodAccessorNH(getWidenedTarget(m), (ExecutableStatement[]) es, getNullMethodHandler()));
            if (o == null)
                o = getNullMethodHandler().getProperty(m.getName(), ctx, variableFactory);
        } else {
            addAccessorNode(new MethodAccessor(getWidenedTarget(m), (ExecutableStatement[]) es));
        }
        /**
       * return the response.
       */
        return o;
    }
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) Function(org.mvel2.ast.Function)

Example 37 with CompileException

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

the class ProtoParser method parse.

public Proto parse() {
    Proto proto = new Proto(protoName);
    Mainloop: while (cursor < endOffset) {
        cursor = ParseTools.skipWhitespace(expr, cursor);
        int start = cursor;
        if (tk2 == null) {
            while (cursor < endOffset && isIdentifierPart(expr[cursor])) cursor++;
            if (cursor > start) {
                tk1 = new String(expr, start, cursor - start);
                if ("def".equals(tk1) || "function".equals(tk1)) {
                    cursor++;
                    cursor = ParseTools.skipWhitespace(expr, cursor);
                    start = cursor;
                    while (cursor < endOffset && isIdentifierPart(expr[cursor])) cursor++;
                    if (start == cursor) {
                        throw new CompileException("attempt to declare an anonymous function as a prototype member", expr, start);
                    }
                    FunctionParser parser = new FunctionParser(new String(expr, start, cursor - start), cursor, endOffset, expr, 0, pCtx, null);
                    proto.declareReceiver(parser.getName(), parser.parse());
                    cursor = parser.getCursor() + 1;
                    tk1 = null;
                    continue;
                }
            }
            cursor = ParseTools.skipWhitespace(expr, cursor);
        }
        if (cursor > endOffset) {
            throw new CompileException("unexpected end of statement in proto declaration: " + protoName, expr, start);
        }
        switch(expr[cursor]) {
            case ';':
                cursor++;
                calculateDecl();
                if (interpreted && type == DeferredTypeResolve.class) {
                    /**
             * If this type could not be immediately resolved, it may be a look-ahead case, so
             * we defer resolution of the type until later and place it in the wait queue.
             */
                    enqueueReceiverForLateResolution(deferredName, proto.declareReceiver(name, Proto.ReceiverType.DEFERRED, null), null);
                } else {
                    proto.declareReceiver(name, type, null);
                }
                break;
            case '=':
                cursor++;
                cursor = ParseTools.skipWhitespace(expr, cursor);
                start = cursor;
                Loop: while (cursor < endOffset) {
                    switch(expr[cursor]) {
                        case '{':
                        case '[':
                        case '(':
                        case '\'':
                        case '"':
                            cursor = balancedCaptureWithLineAccounting(expr, cursor, endOffset, expr[cursor], pCtx);
                            break;
                        case ';':
                            break Loop;
                    }
                    cursor++;
                }
                calculateDecl();
                String initString = new String(expr, start, cursor++ - start);
                if (interpreted && type == DeferredTypeResolve.class) {
                    enqueueReceiverForLateResolution(deferredName, proto.declareReceiver(name, Proto.ReceiverType.DEFERRED, null), initString);
                } else {
                    proto.declareReceiver(name, type, (ExecutableStatement) subCompileExpression(initString, pCtx));
                }
                break;
            default:
                start = cursor;
                while (cursor < endOffset && isIdentifierPart(expr[cursor])) cursor++;
                if (cursor > start) {
                    tk2 = new String(expr, start, cursor - start);
                }
        }
    }
    cursor++;
    /**
     * Check if the function is manually terminated.
     */
    if (splitAccumulator != null && ParseTools.isStatementNotManuallyTerminated(expr, cursor)) {
        /**
       * Add an EndOfStatement to the split accumulator in the parser.
       */
        splitAccumulator.add(new EndOfStatement());
    }
    return proto;
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) Proto(org.mvel2.ast.Proto) EndOfStatement(org.mvel2.ast.EndOfStatement) CompileException(org.mvel2.CompileException)

Example 38 with CompileException

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

the class ProtoParser method checkForPossibleUnresolvedViolations.

/**
   * This is such a horrible hack, but it's more performant than any other horrible hack I can think of
   * right now.
   *
   * @param expr
   * @param cursor
   * @param pCtx
   */
public static void checkForPossibleUnresolvedViolations(char[] expr, int cursor, ParserContext pCtx) {
    if (isUnresolvedWaiting()) {
        LinkedHashMap<String, Object> imports = (LinkedHashMap<String, Object>) pCtx.getParserConfiguration().getImports();
        Object o = imports.values().toArray()[imports.size() - 1];
        if (o instanceof Proto) {
            Proto proto = (Proto) o;
            int last = proto.getCursorEnd();
            cursor--;
            while (cursor > last && ParseTools.isWhitespace(expr[cursor])) cursor--;
            while (cursor > last && ParseTools.isIdentifierPart(expr[cursor])) cursor--;
            while (cursor > last && (ParseTools.isWhitespace(expr[cursor]) || expr[cursor] == ';')) cursor--;
            if (cursor != last) {
                throw new CompileException("unresolved reference (possible illegal forward-reference?): " + ProtoParser.getNextUnresolvedWaiting(), expr, proto.getCursorStart());
            }
        }
    }
}
Also used : Proto(org.mvel2.ast.Proto) CompileException(org.mvel2.CompileException)

Example 39 with CompileException

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

the class CoreConfidenceTests method testStrTriangleEqualsEquals.

public void testStrTriangleEqualsEquals() {
    MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true;
    try {
        ParserConfiguration pconf = new ParserConfiguration();
        ParserContext pctx = new ParserContext(pconf);
        pctx.addInput("this", Triangle.class);
        pctx.setStrongTyping(true);
        String str = "this.strLabel == this";
        try {
            ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx);
            fail("should have failed");
        } catch (CompileException e) {
            System.out.println();
            return;
        }
    } finally {
        MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = false;
    }
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement)

Example 40 with CompileException

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

the class CoreConfidenceTests method testSetAccessorOverloadedEqualsStrictMode.

public void testSetAccessorOverloadedEqualsStrictMode() {
    ParserContext ctx = new ParserContext();
    ctx.setStrongTyping(true);
    ctx.addInput("foo", Foo.class);
    try {
        CompiledExpression expr = new ExpressionCompiler("foo.bar = 0").compile(ctx);
    } catch (CompileException e) {
        // should fail.
        e.printStackTrace();
        return;
    }
    assertTrue(false);
}
Also used : ExpressionCompiler(org.mvel2.compiler.ExpressionCompiler) CompiledExpression(org.mvel2.compiler.CompiledExpression)

Aggregations

CompileException (org.mvel2.CompileException)23 List (java.util.List)8 Map (java.util.Map)8 IOException (java.io.IOException)7 ExecutableStatement (org.mvel2.compiler.ExecutableStatement)7 ArrayList (java.util.ArrayList)6 Function (org.mvel2.ast.Function)4 TypeDescriptor (org.mvel2.ast.TypeDescriptor)4 WeakHashMap (java.util.WeakHashMap)3 ParserContext (org.mvel2.ParserContext)3 Proto (org.mvel2.ast.Proto)3 ExpressionCompiler (org.mvel2.compiler.ExpressionCompiler)3 StringAppender (org.mvel2.util.StringAppender)3 Label (org.mvel2.asm.Label)2 ASTNode (org.mvel2.ast.ASTNode)2 EndOfStatement (org.mvel2.ast.EndOfStatement)2 CompiledExpression (org.mvel2.compiler.CompiledExpression)2 DefaultLocalVariableResolverFactory (org.mvel2.integration.impl.DefaultLocalVariableResolverFactory)2 ItemResolverFactory (org.mvel2.integration.impl.ItemResolverFactory)2 ExecutionStack (org.mvel2.util.ExecutionStack)2