Search in sources :

Example 6 with IfNode

use of org.mvel2.ast.IfNode in project mvel by mikebrock.

the class TemplateCompiler method compileFrom.

public Node compileFrom(Node root, ExecutionStack stack) {
    line = 1;
    Node n = root;
    if (root == null) {
        n = root = new TextNode(0, 0);
    }
    IfNode last;
    Integer opcode;
    String name;
    int x;
    try {
        while (cursor < length) {
            switch(template[cursor]) {
                case '\n':
                    line++;
                    colStart = cursor + 1;
                    break;
                case '@':
                case '$':
                    if (isNext(template[cursor])) {
                        start = ++cursor;
                        (n = markTextNode(n)).setEnd(n.getEnd() + 1);
                        start = lastTextRangeEnding = ++cursor;
                        continue;
                    }
                    if ((x = captureOrbToken()) != -1) {
                        start = x;
                        switch((opcode = OPCODES.get(name = new String(capture()))) == null ? 0 : opcode) {
                            case Opcodes.IF:
                                /**
                                 * Capture any residual text node, and push the if statement on the nesting stack.
                                 */
                                stack.push(n = markTextNode(n).next = codeCache ? new CompiledIfNode(start, name, template, captureOrbInternal(), start, parserContext) : new IfNode(start, name, template, captureOrbInternal(), start));
                                n.setTerminus(new TerminalNode());
                                break;
                            case Opcodes.ELSE:
                                if (!stack.isEmpty() && stack.peek() instanceof IfNode) {
                                    markTextNode(n).next = (last = (IfNode) stack.pop()).getTerminus();
                                    last.demarcate(last.getTerminus(), template);
                                    last.next = n = codeCache ? new CompiledIfNode(start, name, template, captureOrbInternal(), start, parserContext) : new IfNode(start, name, template, captureOrbInternal(), start);
                                    n.setTerminus(last.getTerminus());
                                    stack.push(n);
                                }
                                break;
                            case Opcodes.FOREACH:
                                stack.push(n = markTextNode(n).next = codeCache ? new CompiledForEachNode(start, name, template, captureOrbInternal(), start, parserContext) : new ForEachNode(start, name, template, captureOrbInternal(), start));
                                n.setTerminus(new TerminalNode());
                                break;
                            case Opcodes.INCLUDE_FILE:
                                n = markTextNode(n).next = codeCache ? new CompiledIncludeNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new IncludeNode(start, name, template, captureOrbInternal(), start = cursor + 1);
                                break;
                            case Opcodes.INCLUDE_NAMED:
                                n = markTextNode(n).next = codeCache ? new CompiledNamedIncludeNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new NamedIncludeNode(start, name, template, captureOrbInternal(), start = cursor + 1);
                                break;
                            case Opcodes.CODE:
                                n = markTextNode(n).next = codeCache ? new CompiledCodeNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new CodeNode(start, name, template, captureOrbInternal(), start = cursor + 1);
                                break;
                            case Opcodes.EVAL:
                                n = markTextNode(n).next = codeCache ? new CompiledEvalNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new EvalNode(start, name, template, captureOrbInternal(), start = cursor + 1);
                                break;
                            case Opcodes.COMMENT:
                                n = markTextNode(n).next = new CommentNode(start, name, template, captureOrbInternal(), start = cursor + 1);
                                break;
                            case Opcodes.DECLARE:
                                stack.push(n = markTextNode(n).next = codeCache ? new CompiledDeclareNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new DeclareNode(start, name, template, captureOrbInternal(), start = cursor + 1));
                                n.setTerminus(new TerminalNode());
                                break;
                            case Opcodes.END:
                                n = markTextNode(n);
                                Node end = (Node) stack.pop();
                                Node terminal = end.getTerminus();
                                terminal.setCStart(captureOrbInternal());
                                terminal.setEnd((lastTextRangeEnding = start) - 1);
                                terminal.calculateContents(template);
                                if (end.demarcate(terminal, template))
                                    n = n.next = terminal;
                                else
                                    n = terminal;
                                break;
                            default:
                                if (name.length() == 0) {
                                    n = markTextNode(n).next = codeCache ? new CompiledExpressionNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new ExpressionNode(start, name, template, captureOrbInternal(), start = cursor + 1);
                                } else if (customNodes != null && customNodes.containsKey(name)) {
                                    Class<? extends Node> customNode = customNodes.get(name);
                                    try {
                                        (n = markTextNode(n).next = (customNode.newInstance())).setBegin(start);
                                        n.setName(name);
                                        n.setCStart(captureOrbInternal());
                                        n.setCEnd(start = cursor + 1);
                                        n.setEnd(n.getCEnd());
                                        n.setContents(subset(template, n.getCStart(), n.getCEnd() - n.getCStart() - 1));
                                        if (n.isOpenNode()) {
                                            stack.push(n);
                                        }
                                    } catch (InstantiationException e) {
                                        throw new RuntimeException("unable to instantiate custom node class: " + customNode.getName());
                                    } catch (IllegalAccessException e) {
                                        throw new RuntimeException("unable to instantiate custom node class: " + customNode.getName());
                                    }
                                } else {
                                    throw new RuntimeException("unknown token type: " + name);
                                }
                        }
                    }
                    break;
            }
            cursor++;
        }
    } catch (RuntimeException e) {
        CompileException ce = new CompileException(e.getMessage(), template, cursor, e);
        ce.setExpr(template);
        if (e instanceof CompileException) {
            CompileException ce2 = (CompileException) e;
            if (ce2.getCursor() != -1) {
                ce.setCursor(ce2.getCursor());
                if (ce2.getColumn() == -1)
                    ce.setColumn(ce.getCursor() - colStart);
                else
                    ce.setColumn(ce2.getColumn());
            }
        }
        ce.setLineNumber(line);
        throw ce;
    }
    if (!stack.isEmpty()) {
        CompileException ce = new CompileException("unclosed @" + ((Node) stack.peek()).getName() + "{} block. expected @end{}", template, cursor);
        ce.setColumn(cursor - colStart);
        ce.setLineNumber(line);
        throw ce;
    }
    if (start < template.length) {
        n = n.next = new TextNode(start, template.length);
    }
    n.next = new EndNode();
    n = root;
    do {
        if (n.getLength() != 0) {
            break;
        }
    } while ((n = n.getNext()) != null);
    if (n != null && n.getLength() == template.length - 1) {
        if (n instanceof ExpressionNode) {
            return codeCache ? new CompiledTerminalExpressionNode(n, parserContext) : new TerminalExpressionNode(n);
        } else {
            return n;
        }
    }
    return root;
}
Also used : CompileException(org.mvel2.CompileException)

Aggregations

CompileException (org.mvel2.CompileException)4 IfNode (org.mvel2.ast.IfNode)3 FunctionParser (org.mvel2.util.FunctionParser)2 ProtoParser (org.mvel2.util.ProtoParser)2 ASTNode (org.mvel2.ast.ASTNode)1 DoNode (org.mvel2.ast.DoNode)1 DoUntilNode (org.mvel2.ast.DoUntilNode)1 EndOfStatement (org.mvel2.ast.EndOfStatement)1 ForEachNode (org.mvel2.ast.ForEachNode)1 ForNode (org.mvel2.ast.ForNode)1 Function (org.mvel2.ast.Function)1 Proto (org.mvel2.ast.Proto)1 Stacklang (org.mvel2.ast.Stacklang)1 ThisWithNode (org.mvel2.ast.ThisWithNode)1 UntilNode (org.mvel2.ast.UntilNode)1 WhileNode (org.mvel2.ast.WhileNode)1 WithNode (org.mvel2.ast.WithNode)1