Search in sources :

Example 21 with ExecutableStatement

use of org.mvel2.compiler.ExecutableStatement in project mvel by mikebrock.

the class ForEachNode method handleCond.

private void handleCond(char[] condition, int start, int offset, int fields, ParserContext pCtx) {
    int cursor = start;
    int end = start + offset;
    while (cursor < end && condition[cursor] != ':') cursor++;
    if (cursor == end || condition[cursor] != ':')
        throw new CompileException("expected : in foreach", condition, cursor);
    int x;
    if ((x = (item = createStringTrimmed(condition, start, cursor - start)).indexOf(' ')) != -1) {
        String tk = new String(condition, start, x).trim();
        try {
            itemType = ParseTools.findClass(null, tk, pCtx);
            item = new String(condition, start + x, (cursor - start) - x).trim();
        } catch (ClassNotFoundException e) {
            throw new CompileException("cannot resolve identifier: " + tk, condition, start);
        }
    }
    // this.start = ++cursor;
    this.start = cursor + 1;
    this.offset = offset - (cursor - start) - 1;
    if ((fields & COMPILE_IMMEDIATE) != 0) {
        Class egress = (this.condition = (ExecutableStatement) subCompileExpression(expr, this.start, this.offset, pCtx)).getKnownEgressType();
        if (itemType != null && egress.isArray()) {
            enforceTypeSafety(itemType, getBaseComponentType(this.condition.getKnownEgressType()));
        } else if (pCtx.isStrongTyping()) {
            determineIterType(egress);
        }
    }
}
Also used : CompileException(org.mvel2.CompileException)

Example 22 with ExecutableStatement

use of org.mvel2.compiler.ExecutableStatement 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 23 with ExecutableStatement

use of org.mvel2.compiler.ExecutableStatement 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 24 with ExecutableStatement

use of org.mvel2.compiler.ExecutableStatement in project mvel by mikebrock.

the class GenericsTypeInferenceTest method testAmazed.

public void testAmazed() {
    MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true;
    try {
        ParserContext context = new ParserContext();
        context.setStrongTyping(true);
        context.addInput("this", Amazed1.class);
        ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression("list.size", context);
        Amazed1 a1 = new Amazed1();
        assertEquals(new Integer(0), MVEL.executeExpression(stmt, a1));
        context = new ParserContext();
        context.setStrongTyping(true);
        context.addInput("this", Amazed2.class);
        stmt = (ExecutableStatement) MVEL.compileExpression("list.size", context);
        Amazed2 a2 = new Amazed2();
        assertEquals(new Integer(0), MVEL.executeExpression(stmt, a2));
    } finally {
        MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = false;
    }
}
Also used : ParserContext(org.mvel2.ParserContext)

Example 25 with ExecutableStatement

use of org.mvel2.compiler.ExecutableStatement in project mvel by mikebrock.

the class CoreConfidenceTests method testContextFieldNotFound.

public void testContextFieldNotFound() {
    String str = "'stilton'.equals( type );";
    ParserConfiguration pconf = new ParserConfiguration();
    ParserContext pctx = new ParserContext(pconf);
    pctx.addInput("this", Cheese.class);
    pctx.setStrictTypeEnforcement(true);
    pctx.setStrongTyping(true);
    ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx);
    MVEL.executeExpression(stmt, new Cheese(), new HashMap());
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement)

Aggregations

ExecutableStatement (org.mvel2.compiler.ExecutableStatement)25 IOException (java.io.IOException)6 ParserContext (org.mvel2.ParserContext)6 List (java.util.List)5 Map (java.util.Map)5 CompileException (org.mvel2.CompileException)4 TypeDescriptor (org.mvel2.ast.TypeDescriptor)4 ArrayList (java.util.ArrayList)3 ParserConfiguration (org.mvel2.ParserConfiguration)3 WeakHashMap (java.util.WeakHashMap)2 Union (org.mvel2.optimizers.impl.refl.nodes.Union)2 PropertyTools.getFieldOrAccessor (org.mvel2.util.PropertyTools.getFieldOrAccessor)2 PropertyTools.getFieldOrWriteAccessor (org.mvel2.util.PropertyTools.getFieldOrWriteAccessor)2 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Label (org.mvel2.asm.Label)1 MethodVisitor (org.mvel2.asm.MethodVisitor)1 EndOfStatement (org.mvel2.ast.EndOfStatement)1 Function (org.mvel2.ast.Function)1 Proto (org.mvel2.ast.Proto)1