protected void getVariables()

in src/main/java/org/apache/commons/jexl3/internal/Engine.java [884:941]


    protected void getVariables(final ASTJexlScript script, final JexlNode node, final VarCollector collector) {
        if (node instanceof ASTIdentifier) {
            final JexlNode parent = node.jjtGetParent();
            if (parent instanceof ASTMethodNode || parent instanceof ASTFunctionNode) {
                // skip identifiers for methods and functions
                collector.collect(null);
                return;
            }
            final ASTIdentifier identifier = (ASTIdentifier) node;
            final int symbol = identifier.getSymbol();
            // symbols that are captured are considered "global" variables
            if (symbol >= 0 && script != null && !script.isCapturedSymbol(symbol)) {
                collector.collect(null);
            } else {
                // start collecting from identifier
                collector.collect(identifier);
                collector.add(identifier.getName());
            }
        } else if (node instanceof ASTIdentifierAccess) {
            final JexlNode parent = node.jjtGetParent();
            if (parent instanceof ASTMethodNode || parent instanceof ASTFunctionNode) {
                // skip identifiers for methods and functions
                collector.collect(null);
                return;
            }
            // belt and suspender since an identifier should have been seen first
            if (collector.isCollecting()) {
                collector.add(((ASTIdentifierAccess) node).getName());
            }
        } else if (node instanceof ASTArrayAccess && collector.mode > 0) {
            final int num = node.jjtGetNumChildren();
            // collect only if array access is const and follows an identifier
            boolean collecting = collector.isCollecting();
            for (int i = 0; i < num; ++i) {
                final JexlNode child = node.jjtGetChild(i);
                if (collecting && child.isConstant()) {
                    // collect all constants or only string and number literals
                    final boolean collect = collector.mode > 1
                            || (child instanceof ASTStringLiteral || child instanceof ASTNumberLiteral);
                    if (collect) {
                        final String image = child.toString();
                        collector.add(image);
                    }
                } else {
                    collecting = false;
                    collector.collect(null);
                    getVariables(script, child, collector);
                    collector.collect(null);
                }
            }
        } else {
            final int num = node.jjtGetNumChildren();
            for (int i = 0; i < num; ++i) {
                getVariables(script, node.jjtGetChild(i), collector);
            }
            collector.collect(null);
        }
    }