Number evaluate()

in src/main/groovy/groovyShell/ArithmeticShell.groovy [62:156]


    Number evaluate(String text) {
        try {
            final ImportCustomizer imports = new ImportCustomizer().addStaticStars('java.lang.Math') // add static import of java.lang.Math
            final SecureASTCustomizer secure = new SecureASTCustomizer()
            secure.with {
                closuresAllowed = false
                methodDefinitionAllowed = false
                
                importsWhitelist = []
                staticImportsWhitelist = []
                staticStarImportsWhitelist = ['java.lang.Math'] // only java.lang.Math is allowed

                tokensWhitelist = [
                        PLUS,
                        MINUS,
                        MULTIPLY,
                        DIVIDE,
                        MOD,
                        POWER,
                        PLUS_PLUS,
                        MINUS_MINUS,
                        COMPARE_EQUAL,
                        COMPARE_NOT_EQUAL,
                        COMPARE_LESS_THAN,
                        COMPARE_LESS_THAN_EQUAL,
                        COMPARE_GREATER_THAN,
                        COMPARE_GREATER_THAN_EQUAL,
                ].asImmutable()

                constantTypesClassesWhiteList = [
                        Integer,
                        Float,
                        Long,
                        Double,
                        BigDecimal,
                        Integer.TYPE,
                        Long.TYPE,
                        Float.TYPE,
                        Double.TYPE
                ].asImmutable()

                receiversClassesWhiteList = [
                        Math,
                        Integer,
                        Float,
                        Double,
                        Long,
                        BigDecimal
                ].asImmutable()

                statementsWhitelist = [
                        BlockStatement,
                        ExpressionStatement
                ].asImmutable()

                expressionsWhitelist = [
                        BinaryExpression,
                        ConstantExpression,
                        MethodCallExpression,
                        StaticMethodCallExpression,
                        ArgumentListExpression,
                        PropertyExpression,
                        UnaryMinusExpression,
                        UnaryPlusExpression,
                        PrefixExpression,
                        PostfixExpression,
                        TernaryExpression,
                        ElvisOperatorExpression,
                        BooleanExpression,
                        // ClassExpression needed for processing of MethodCallExpression, PropertyExpression
                        // and StaticMethodCallExpression
                  ClassExpression
                ].asImmutable()

            }
            CompilerConfiguration config = new CompilerConfiguration()
            config.addCompilationCustomizers(imports, secure)
            GroovyClassLoader loader = new GroovyClassLoader(this.class.classLoader, config)
            Class clazz = loader.parseClass(text)
            Script script = (Script) clazz.newInstance();
            Object result = script.run()
            if (!(result instanceof Number)) throw new IllegalStateException("Script returned a non-number: $result");
            return (Number) result
        } catch (SecurityException ex) {
            throw new SecurityException("Could not evaluate script: $text", ex)
        } catch (MultipleCompilationErrorsException mce) {
            //this allows compilation errors to be seen by the user       
            mce.errorCollector.errors.each {
                if (it instanceof ExceptionMessage && it.cause instanceof SecurityException) {
                    throw it.cause
                }
            }
            throw mce
        }
    }