Search in sources :

Example 1 with Cast

use of org.elasticsearch.painless.Definition.Cast in project elasticsearch by elastic.

the class AnalyzerCaster method getLegalCast.

public static Cast getLegalCast(Location location, Type actual, Type expected, boolean explicit, boolean internal) {
    Objects.requireNonNull(actual);
    Objects.requireNonNull(expected);
    if (actual.equals(expected)) {
        return null;
    }
    switch(actual.sort) {
        case BOOL:
            switch(expected.sort) {
                case DEF:
                    return new Cast(BOOLEAN_OBJ_TYPE, DEF_TYPE, explicit, null, null, BOOLEAN_TYPE, null);
                case OBJECT:
                    if (OBJECT_TYPE.equals(expected) && internal)
                        return new Cast(BOOLEAN_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, BOOLEAN_TYPE, null);
                    break;
                case BOOL_OBJ:
                    if (internal)
                        return new Cast(BOOLEAN_TYPE, BOOLEAN_TYPE, explicit, null, null, null, BOOLEAN_TYPE);
            }
            break;
        case BYTE:
            switch(expected.sort) {
                case SHORT:
                case INT:
                case LONG:
                case FLOAT:
                case DOUBLE:
                    return new Cast(BYTE_TYPE, expected, explicit);
                case CHAR:
                    if (explicit)
                        return new Cast(BYTE_TYPE, CHAR_TYPE, true);
                    break;
                case DEF:
                    return new Cast(BYTE_OBJ_TYPE, DEF_TYPE, explicit, null, null, BYTE_TYPE, null);
                case OBJECT:
                    if (OBJECT_TYPE.equals(expected) && internal)
                        return new Cast(BYTE_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, BYTE_TYPE, null);
                    break;
                case NUMBER:
                    if (internal)
                        return new Cast(BYTE_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, BYTE_TYPE, null);
                    break;
                case BYTE_OBJ:
                    if (internal)
                        return new Cast(BYTE_TYPE, BYTE_TYPE, explicit, null, null, null, BYTE_TYPE);
                    break;
                case SHORT_OBJ:
                    if (internal)
                        return new Cast(BYTE_TYPE, SHORT_TYPE, explicit, null, null, null, SHORT_TYPE);
                    break;
                case INT_OBJ:
                    if (internal)
                        return new Cast(BYTE_TYPE, INT_TYPE, explicit, null, null, null, INT_TYPE);
                    break;
                case LONG_OBJ:
                    if (internal)
                        return new Cast(BYTE_TYPE, LONG_TYPE, explicit, null, null, null, LONG_TYPE);
                    break;
                case FLOAT_OBJ:
                    if (internal)
                        return new Cast(BYTE_TYPE, FLOAT_TYPE, explicit, null, null, null, FLOAT_TYPE);
                    break;
                case DOUBLE_OBJ:
                    if (internal)
                        return new Cast(BYTE_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
                    break;
                case CHAR_OBJ:
                    if (explicit && internal)
                        return new Cast(BYTE_TYPE, CHAR_TYPE, true, null, null, null, CHAR_TYPE);
                    break;
            }
            break;
        case SHORT:
            switch(expected.sort) {
                case INT:
                case LONG:
                case FLOAT:
                case DOUBLE:
                    return new Cast(SHORT_TYPE, expected, explicit);
                case BYTE:
                case CHAR:
                    if (explicit)
                        return new Cast(SHORT_TYPE, expected, true);
                    break;
                case DEF:
                    return new Cast(SHORT_OBJ_TYPE, DEF_TYPE, explicit, null, null, SHORT_TYPE, null);
                case OBJECT:
                    if (OBJECT_TYPE.equals(expected) && internal)
                        return new Cast(SHORT_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, SHORT_TYPE, null);
                    break;
                case NUMBER:
                    if (internal)
                        return new Cast(SHORT_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, SHORT_TYPE, null);
                    break;
                case SHORT_OBJ:
                    if (internal)
                        return new Cast(SHORT_TYPE, SHORT_TYPE, explicit, null, null, null, SHORT_TYPE);
                    break;
                case INT_OBJ:
                    if (internal)
                        return new Cast(SHORT_TYPE, INT_TYPE, explicit, null, null, null, INT_TYPE);
                    break;
                case LONG_OBJ:
                    if (internal)
                        return new Cast(SHORT_TYPE, LONG_TYPE, explicit, null, null, null, LONG_TYPE);
                    break;
                case FLOAT_OBJ:
                    if (internal)
                        return new Cast(SHORT_TYPE, FLOAT_TYPE, explicit, null, null, null, FLOAT_TYPE);
                    break;
                case DOUBLE_OBJ:
                    if (internal)
                        return new Cast(SHORT_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
                    break;
                case BYTE_OBJ:
                    if (explicit && internal)
                        return new Cast(SHORT_TYPE, BYTE_TYPE, true, null, null, null, BYTE_TYPE);
                    break;
                case CHAR_OBJ:
                    if (explicit && internal)
                        return new Cast(SHORT_TYPE, CHAR_TYPE, true, null, null, null, CHAR_TYPE);
                    break;
            }
            break;
        case CHAR:
            switch(expected.sort) {
                case INT:
                case LONG:
                case FLOAT:
                case DOUBLE:
                    return new Cast(CHAR_TYPE, expected, explicit);
                case BYTE:
                case SHORT:
                    if (explicit)
                        return new Cast(actual, expected, true);
                    break;
                case DEF:
                    return new Cast(CHAR_OBJ_TYPE, DEF_TYPE, explicit, null, null, CHAR_TYPE, null);
                case OBJECT:
                    if (OBJECT_TYPE.equals(expected) && internal)
                        return new Cast(CHAR_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, CHAR_TYPE, null);
                    break;
                case NUMBER:
                    if (internal)
                        return new Cast(CHAR_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, CHAR_TYPE, null);
                    break;
                case CHAR_OBJ:
                    if (internal)
                        return new Cast(CHAR_TYPE, CHAR_TYPE, explicit, null, null, null, CHAR_TYPE);
                    break;
                case STRING:
                    return new Cast(CHAR_TYPE, STRING_TYPE, explicit);
                case INT_OBJ:
                    if (internal)
                        return new Cast(CHAR_TYPE, INT_TYPE, explicit, null, null, null, INT_TYPE);
                    break;
                case LONG_OBJ:
                    if (internal)
                        return new Cast(CHAR_TYPE, LONG_TYPE, explicit, null, null, null, LONG_TYPE);
                    break;
                case FLOAT_OBJ:
                    if (internal)
                        return new Cast(CHAR_TYPE, FLOAT_TYPE, explicit, null, null, null, FLOAT_TYPE);
                    break;
                case DOUBLE_OBJ:
                    if (internal)
                        return new Cast(CHAR_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
                    break;
                case BYTE_OBJ:
                    if (explicit && internal)
                        return new Cast(CHAR_TYPE, BYTE_TYPE, true, null, null, null, BYTE_TYPE);
                    break;
                case SHORT_OBJ:
                    if (explicit && internal)
                        return new Cast(CHAR_TYPE, SHORT_TYPE, true, null, null, null, SHORT_TYPE);
                    break;
            }
            break;
        case INT:
            switch(expected.sort) {
                case LONG:
                case FLOAT:
                case DOUBLE:
                    return new Cast(INT_TYPE, expected, explicit);
                case BYTE:
                case SHORT:
                case CHAR:
                    if (explicit)
                        return new Cast(INT_TYPE, expected, true);
                    break;
                case DEF:
                    return new Cast(INT_OBJ_TYPE, DEF_TYPE, explicit, null, null, INT_TYPE, null);
                case OBJECT:
                    if (OBJECT_TYPE.equals(expected) && internal)
                        return new Cast(INT_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, INT_TYPE, null);
                    break;
                case NUMBER:
                    if (internal)
                        return new Cast(INT_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, INT_TYPE, null);
                    break;
                case INT_OBJ:
                    if (internal)
                        return new Cast(INT_TYPE, INT_TYPE, explicit, null, null, null, INT_TYPE);
                    break;
                case LONG_OBJ:
                    if (internal)
                        return new Cast(INT_TYPE, LONG_TYPE, explicit, null, null, null, LONG_TYPE);
                    break;
                case FLOAT_OBJ:
                    if (internal)
                        return new Cast(INT_TYPE, FLOAT_TYPE, explicit, null, null, null, FLOAT_TYPE);
                    break;
                case DOUBLE_OBJ:
                    if (internal)
                        return new Cast(INT_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
                    break;
                case BYTE_OBJ:
                    if (explicit && internal)
                        return new Cast(INT_TYPE, BYTE_TYPE, true, null, null, null, BYTE_TYPE);
                    break;
                case SHORT_OBJ:
                    if (explicit && internal)
                        return new Cast(INT_TYPE, SHORT_TYPE, true, null, null, null, SHORT_TYPE);
                    break;
                case CHAR_OBJ:
                    if (explicit && internal)
                        return new Cast(INT_TYPE, CHAR_TYPE, true, null, null, null, CHAR_TYPE);
                    break;
            }
            break;
        case LONG:
            switch(expected.sort) {
                case FLOAT:
                case DOUBLE:
                    return new Cast(LONG_TYPE, expected, explicit);
                case BYTE:
                case SHORT:
                case CHAR:
                case INT:
                    if (explicit)
                        return new Cast(actual, expected, true);
                    break;
                case DEF:
                    return new Cast(LONG_TYPE, DEF_TYPE, explicit, null, null, LONG_TYPE, null);
                case OBJECT:
                    if (OBJECT_TYPE.equals(expected) && internal)
                        return new Cast(LONG_TYPE, actual, explicit, null, null, LONG_TYPE, null);
                    break;
                case NUMBER:
                    if (internal)
                        return new Cast(LONG_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, LONG_TYPE, null);
                    break;
                case LONG_OBJ:
                    if (internal)
                        return new Cast(LONG_TYPE, LONG_TYPE, explicit, null, null, null, LONG_TYPE);
                    break;
                case FLOAT_OBJ:
                    if (internal)
                        return new Cast(LONG_TYPE, FLOAT_TYPE, explicit, null, null, null, FLOAT_TYPE);
                    break;
                case DOUBLE_OBJ:
                    if (internal)
                        return new Cast(LONG_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
                    break;
                case BYTE_OBJ:
                    if (explicit && internal)
                        return new Cast(LONG_TYPE, BYTE_TYPE, true, null, null, null, BYTE_TYPE);
                    break;
                case SHORT_OBJ:
                    if (explicit && internal)
                        return new Cast(LONG_TYPE, SHORT_TYPE, true, null, null, null, SHORT_TYPE);
                    break;
                case CHAR_OBJ:
                    if (explicit && internal)
                        return new Cast(LONG_TYPE, CHAR_TYPE, true, null, null, null, CHAR_TYPE);
                    break;
                case INT_OBJ:
                    if (explicit && internal)
                        return new Cast(LONG_TYPE, INT_TYPE, true, null, null, null, INT_TYPE);
                    break;
            }
            break;
        case FLOAT:
            switch(expected.sort) {
                case DOUBLE:
                    return new Cast(actual, expected, explicit);
                case BYTE:
                case SHORT:
                case CHAR:
                case INT:
                case FLOAT:
                    if (explicit)
                        return new Cast(actual, expected, true);
                    break;
                case DEF:
                    return new Cast(FLOAT_OBJ_TYPE, DEF_TYPE, explicit, null, null, FLOAT_TYPE, null);
                case OBJECT:
                    if (OBJECT_TYPE.equals(expected) && internal)
                        return new Cast(FLOAT_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, FLOAT_TYPE, null);
                    break;
                case NUMBER:
                    if (internal)
                        return new Cast(FLOAT_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, FLOAT_TYPE, null);
                    break;
                case FLOAT_OBJ:
                    if (internal)
                        return new Cast(FLOAT_TYPE, FLOAT_TYPE, explicit, null, null, null, FLOAT_TYPE);
                    break;
                case DOUBLE_OBJ:
                    if (internal)
                        return new Cast(FLOAT_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
                    break;
                case BYTE_OBJ:
                    if (explicit && internal)
                        return new Cast(FLOAT_TYPE, BYTE_TYPE, true, null, null, null, BYTE_TYPE);
                    break;
                case SHORT_OBJ:
                    if (explicit && internal)
                        return new Cast(FLOAT_TYPE, SHORT_TYPE, true, null, null, null, SHORT_TYPE);
                    break;
                case CHAR_OBJ:
                    if (explicit && internal)
                        return new Cast(FLOAT_TYPE, CHAR_TYPE, true, null, null, null, CHAR_TYPE);
                    break;
                case INT_OBJ:
                    if (explicit && internal)
                        return new Cast(FLOAT_TYPE, INT_TYPE, true, null, null, null, INT_TYPE);
                    break;
                case LONG_OBJ:
                    if (explicit && internal)
                        return new Cast(FLOAT_TYPE, LONG_TYPE, true, null, null, null, LONG_TYPE);
                    break;
            }
            break;
        case DOUBLE:
            switch(expected.sort) {
                case BYTE:
                case SHORT:
                case CHAR:
                case INT:
                case FLOAT:
                    if (explicit)
                        return new Cast(DOUBLE_TYPE, expected, true);
                    break;
                case DEF:
                    return new Cast(DOUBLE_OBJ_TYPE, DEF_TYPE, explicit, null, null, DOUBLE_TYPE, null);
                case OBJECT:
                    if (OBJECT_TYPE.equals(expected) && internal)
                        return new Cast(DOUBLE_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, DOUBLE_TYPE, null);
                    break;
                case NUMBER:
                    if (internal)
                        return new Cast(DOUBLE_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, DOUBLE_TYPE, null);
                    break;
                case DOUBLE_OBJ:
                    if (internal)
                        return new Cast(DOUBLE_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
                    break;
                case BYTE_OBJ:
                    if (explicit && internal)
                        return new Cast(DOUBLE_TYPE, BYTE_TYPE, true, null, null, null, BYTE_TYPE);
                    break;
                case SHORT_OBJ:
                    if (explicit && internal)
                        return new Cast(DOUBLE_TYPE, SHORT_TYPE, true, null, null, null, SHORT_TYPE);
                    break;
                case CHAR_OBJ:
                    if (explicit && internal)
                        return new Cast(DOUBLE_TYPE, CHAR_TYPE, true, null, null, null, CHAR_TYPE);
                    break;
                case INT_OBJ:
                    if (explicit && internal)
                        return new Cast(DOUBLE_TYPE, INT_TYPE, true, null, null, null, INT_TYPE);
                    break;
                case LONG_OBJ:
                    if (explicit && internal)
                        return new Cast(DOUBLE_TYPE, LONG_TYPE, true, null, null, null, LONG_TYPE);
                    break;
                case FLOAT_OBJ:
                    if (explicit && internal)
                        return new Cast(DOUBLE_TYPE, FLOAT_TYPE, true, null, null, null, FLOAT_TYPE);
                    break;
            }
            break;
        case OBJECT:
            if (OBJECT_TYPE.equals(actual))
                switch(expected.sort) {
                    case BYTE:
                        if (internal && explicit)
                            return new Cast(OBJECT_TYPE, BYTE_OBJ_TYPE, true, null, BYTE_TYPE, null, null);
                        break;
                    case SHORT:
                        if (internal && explicit)
                            return new Cast(OBJECT_TYPE, SHORT_OBJ_TYPE, true, null, SHORT_TYPE, null, null);
                        break;
                    case CHAR:
                        if (internal && explicit)
                            return new Cast(OBJECT_TYPE, CHAR_OBJ_TYPE, true, null, CHAR_TYPE, null, null);
                        break;
                    case INT:
                        if (internal && explicit)
                            return new Cast(OBJECT_TYPE, INT_OBJ_TYPE, true, null, INT_TYPE, null, null);
                        break;
                    case LONG:
                        if (internal && explicit)
                            return new Cast(OBJECT_TYPE, LONG_OBJ_TYPE, true, null, LONG_TYPE, null, null);
                        break;
                    case FLOAT:
                        if (internal && explicit)
                            return new Cast(OBJECT_TYPE, FLOAT_OBJ_TYPE, true, null, FLOAT_TYPE, null, null);
                        break;
                    case DOUBLE:
                        if (internal && explicit)
                            return new Cast(OBJECT_TYPE, DOUBLE_OBJ_TYPE, true, null, DOUBLE_TYPE, null, null);
                        break;
                }
            break;
        case NUMBER:
            switch(expected.sort) {
                case BYTE:
                    if (internal && explicit)
                        return new Cast(NUMBER_TYPE, BYTE_OBJ_TYPE, true, null, BYTE_TYPE, null, null);
                    break;
                case SHORT:
                    if (internal && explicit)
                        return new Cast(NUMBER_TYPE, SHORT_OBJ_TYPE, true, null, SHORT_TYPE, null, null);
                    break;
                case CHAR:
                    if (internal && explicit)
                        return new Cast(NUMBER_TYPE, CHAR_OBJ_TYPE, true, null, CHAR_TYPE, null, null);
                    break;
                case INT:
                    if (internal && explicit)
                        return new Cast(NUMBER_TYPE, INT_OBJ_TYPE, true, null, INT_TYPE, null, null);
                    break;
                case LONG:
                    if (internal && explicit)
                        return new Cast(NUMBER_TYPE, LONG_OBJ_TYPE, true, null, LONG_TYPE, null, null);
                    break;
                case FLOAT:
                    if (internal && explicit)
                        return new Cast(NUMBER_TYPE, FLOAT_OBJ_TYPE, true, null, FLOAT_TYPE, null, null);
                    break;
                case DOUBLE:
                    if (internal && explicit)
                        return new Cast(NUMBER_TYPE, DOUBLE_OBJ_TYPE, true, null, DOUBLE_TYPE, null, null);
                    break;
            }
            break;
        case BOOL_OBJ:
            switch(expected.sort) {
                case BOOL:
                    if (internal)
                        return new Cast(BOOLEAN_TYPE, BOOLEAN_TYPE, explicit, BOOLEAN_TYPE, null, null, null);
                    break;
            }
            break;
        case BYTE_OBJ:
            switch(expected.sort) {
                case BYTE:
                case SHORT:
                case INT:
                case LONG:
                case FLOAT:
                case DOUBLE:
                    if (internal)
                        return new Cast(BYTE_TYPE, expected, explicit, BYTE_TYPE, null, null, null);
                    break;
                case CHAR:
                    if (internal && explicit)
                        return new Cast(BYTE_TYPE, expected, true, BYTE_TYPE, null, null, null);
                    break;
            }
            break;
        case SHORT_OBJ:
            switch(expected.sort) {
                case SHORT:
                case INT:
                case LONG:
                case FLOAT:
                case DOUBLE:
                    if (internal)
                        return new Cast(SHORT_TYPE, expected, explicit, SHORT_TYPE, null, null, null);
                    break;
                case BYTE:
                case CHAR:
                    if (internal && explicit)
                        return new Cast(SHORT_TYPE, expected, true, SHORT_TYPE, null, null, null);
                    break;
            }
            break;
        case CHAR_OBJ:
            switch(expected.sort) {
                case CHAR:
                case INT:
                case LONG:
                case FLOAT:
                case DOUBLE:
                    if (internal)
                        return new Cast(CHAR_TYPE, expected, explicit, CHAR_TYPE, null, null, null);
                    break;
                case BYTE:
                case SHORT:
                    if (internal && explicit)
                        return new Cast(CHAR_TYPE, expected, true, CHAR_TYPE, null, null, null);
                    break;
            }
            break;
        case INT_OBJ:
            switch(expected.sort) {
                case INT:
                case LONG:
                case FLOAT:
                case DOUBLE:
                    if (internal)
                        return new Cast(INT_TYPE, expected, explicit, INT_TYPE, null, null, null);
                    break;
                case BYTE:
                case SHORT:
                case CHAR:
                    if (internal && explicit)
                        return new Cast(INT_TYPE, expected, true, INT_TYPE, null, null, null);
                    break;
            }
            break;
        case LONG_OBJ:
            switch(expected.sort) {
                case LONG:
                case FLOAT:
                case DOUBLE:
                    if (internal)
                        return new Cast(LONG_TYPE, expected, explicit, LONG_TYPE, null, null, null);
                    break;
                case BYTE:
                case SHORT:
                case CHAR:
                case INT:
                    if (internal && explicit)
                        return new Cast(LONG_TYPE, expected, true, LONG_TYPE, null, null, null);
                    break;
            }
            break;
        case FLOAT_OBJ:
            switch(expected.sort) {
                case FLOAT:
                case DOUBLE:
                    if (internal)
                        return new Cast(FLOAT_TYPE, expected, explicit, FLOAT_TYPE, null, null, null);
                    break;
                case BYTE:
                case SHORT:
                case CHAR:
                case INT:
                case LONG:
                    if (internal && explicit)
                        return new Cast(FLOAT_TYPE, expected, true, FLOAT_TYPE, null, null, null);
                    break;
            }
            break;
        case DOUBLE_OBJ:
            switch(expected.sort) {
                case DOUBLE:
                    if (internal)
                        return new Cast(DOUBLE_TYPE, expected, explicit, DOUBLE_TYPE, null, null, null);
                    break;
                case BYTE:
                case SHORT:
                case CHAR:
                case INT:
                case LONG:
                case FLOAT:
                    if (internal && explicit)
                        return new Cast(DOUBLE_TYPE, expected, true, DOUBLE_TYPE, null, null, null);
                    break;
            }
            break;
        case DEF:
            switch(expected.sort) {
                case BOOL:
                    return new Cast(DEF_TYPE, BOOLEAN_OBJ_TYPE, explicit, null, BOOLEAN_TYPE, null, null);
                case BYTE:
                    return new Cast(DEF_TYPE, BYTE_OBJ_TYPE, explicit, null, BYTE_TYPE, null, null);
                case SHORT:
                    return new Cast(DEF_TYPE, SHORT_OBJ_TYPE, explicit, null, SHORT_TYPE, null, null);
                case CHAR:
                    return new Cast(DEF_TYPE, CHAR_OBJ_TYPE, explicit, null, CHAR_TYPE, null, null);
                case INT:
                    return new Cast(DEF_TYPE, INT_OBJ_TYPE, explicit, null, INT_TYPE, null, null);
                case LONG:
                    return new Cast(DEF_TYPE, LONG_OBJ_TYPE, explicit, null, LONG_TYPE, null, null);
                case FLOAT:
                    return new Cast(DEF_TYPE, FLOAT_OBJ_TYPE, explicit, null, FLOAT_TYPE, null, null);
                case DOUBLE:
                    return new Cast(DEF_TYPE, DOUBLE_OBJ_TYPE, explicit, null, DOUBLE_TYPE, null, null);
            }
            break;
        case STRING:
            switch(expected.sort) {
                case CHAR:
                    if (explicit)
                        return new Cast(STRING_TYPE, CHAR_TYPE, true);
                    break;
            }
            break;
    }
    if (actual.sort == Sort.DEF || (actual.sort != Sort.VOID && expected.sort == Sort.DEF) || expected.clazz.isAssignableFrom(actual.clazz) || (explicit && actual.clazz.isAssignableFrom(expected.clazz))) {
        return new Cast(actual, expected, explicit);
    } else {
        throw location.createError(new ClassCastException("Cannot cast from [" + actual.name + "] to [" + expected.name + "]."));
    }
}
Also used : Cast(org.elasticsearch.painless.Definition.Cast)

Example 2 with Cast

use of org.elasticsearch.painless.Definition.Cast in project elasticsearch by elastic.

the class AExpression method cast.

/**
     * Inserts {@link ECast} nodes into the tree for implicit casts.  Also replaces
     * nodes with the constant variable set to a non-null value with {@link EConstant}.
     * @return The new child node for the parent node calling this method.
     */
AExpression cast(Locals locals) {
    Cast cast = AnalyzerCaster.getLegalCast(location, actual, expected, explicit, internal);
    if (cast == null) {
        if (constant == null || this instanceof EConstant) {
            return this;
        } else {
            // For the case where a cast is not required but a
            // constant is set, an EConstant replaces this node
            // with the constant copied from this node.  Note that
            // for constants output data does not need to be copied
            // from this node because the output data for the EConstant
            // will already be the same.
            EConstant econstant = new EConstant(location, constant);
            econstant.analyze(locals);
            if (!expected.equals(econstant.actual)) {
                throw createError(new IllegalStateException("Illegal tree structure."));
            }
            return econstant;
        }
    } else {
        if (constant == null) {
            // For the case where a cast is required and a constant is not set.
            // Modify the tree to add an ECast between this node and its parent.
            // The output data from this node is copied to the ECast for
            // further reads done by the parent.
            ECast ecast = new ECast(location, this, cast);
            ecast.statement = statement;
            ecast.actual = expected;
            ecast.isNull = isNull;
            return ecast;
        } else {
            if (expected.sort.constant) {
                // For the case where a cast is required, a constant is set,
                // and the constant can be immediately cast to the expected type.
                // An EConstant replaces this node with the constant cast appropriately
                // from the constant value defined by this node.  Note that
                // for constants output data does not need to be copied
                // from this node because the output data for the EConstant
                // will already be the same.
                constant = AnalyzerCaster.constCast(location, constant, cast);
                EConstant econstant = new EConstant(location, constant);
                econstant.analyze(locals);
                if (!expected.equals(econstant.actual)) {
                    throw createError(new IllegalStateException("Illegal tree structure."));
                }
                return econstant;
            } else if (this instanceof EConstant) {
                // For the case where a cast is required, a constant is set,
                // the constant cannot be immediately cast to the expected type,
                // and this node is already an EConstant.  Modify the tree to add
                // an ECast between this node and its parent.  Note that
                // for constants output data does not need to be copied
                // from this node because the output data for the EConstant
                // will already be the same.
                ECast ecast = new ECast(location, this, cast);
                ecast.actual = expected;
                return ecast;
            } else {
                // For the case where a cast is required, a constant is set,
                // the constant cannot be immediately cast to the expected type,
                // and this node is not an EConstant.  Replace this node with
                // an Econstant node copying the constant from this node.
                // Modify the tree to add an ECast between the EConstant node
                // and its parent.  Note that for constants output data does not
                // need to be copied from this node because the output data for
                // the EConstant will already be the same.
                EConstant econstant = new EConstant(location, constant);
                econstant.analyze(locals);
                if (!actual.equals(econstant.actual)) {
                    throw createError(new IllegalStateException("Illegal tree structure."));
                }
                ECast ecast = new ECast(location, econstant, cast);
                ecast.actual = expected;
                return ecast;
            }
        }
    }
}
Also used : Cast(org.elasticsearch.painless.Definition.Cast)

Example 3 with Cast

use of org.elasticsearch.painless.Definition.Cast in project elasticsearch by elastic.

the class NodeToStringTests method testECast.

public void testECast() {
    Location l = new Location(getTestName(), 0);
    AExpression child = new EConstant(l, "test");
    Cast cast = new Cast(Definition.STRING_TYPE, Definition.INT_OBJ_TYPE, true);
    assertEquals("(ECast Integer (EConstant String 'test'))", new ECast(l, child, cast).toString());
    l = new Location(getTestName(), 1);
    child = new EBinary(l, Operation.ADD, new EConstant(l, "test"), new EConstant(l, 12));
    cast = new Cast(Definition.INT_OBJ_TYPE, Definition.BOOLEAN_OBJ_TYPE, true);
    assertEquals("(ECast Boolean (EBinary (EConstant String 'test') + (EConstant Integer 12)))", new ECast(l, child, cast).toString());
}
Also used : Cast(org.elasticsearch.painless.Definition.Cast) Location(org.elasticsearch.painless.Location)

Aggregations

Cast (org.elasticsearch.painless.Definition.Cast)3 Location (org.elasticsearch.painless.Location)1