/* * Copyright (C) 2015 SoftIndex LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.datakernel.codegen; import org.objectweb.asm.Type; import java.util.ArrayList; import java.util.List; import static io.datakernel.codegen.ExpressionComparator.*; import static java.util.Arrays.asList; import static org.objectweb.asm.Type.getType; /** * Defines list of possibilities for creating the dynamic object */ public final class Expressions { private Expressions() { } public static Expression sequence(List<Expression> parts) { return new ExpressionSequence(parts); } /** * Returns sequence of operations which will be processed one after the other * * @param parts list of operations * @return new instance of the ExpressionSequence */ public static Expression sequence(Expression... parts) { return new ExpressionSequence(asList(parts)); } /** * Return new variable which will process expression * * @param expression expression which will be processed when variable will be used * @return new instance of the Expression */ public static Variable let(Expression expression) { return new ExpressionLet(expression); } /** * Sets the value from argument 'from' in argument 'to' * * @param to variable which will be changed * @param from variable which will change * @return new instance of the Expression */ public static Expression set(StoreDef to, Expression from) { return new ExpressionSet(to, from); } /** * Casts expression to the type * * @param expression expressions which will be casted * @param type expression will be casted to the 'type' * @return new instance of the Expression which is casted to the type */ public static Expression cast(Expression expression, Type type) { return new ExpressionCast(expression, type); } /** * Casts expression to the type * * @param expression expressions which will be casted * @param type expression will be casted to the 'type' * @return new instance of the Expression which is casted to the type */ public static Expression cast(Expression expression, Class<?> type) { return cast(expression, getType(type)); } /** * Returns the field from owner * * @param owner owner of the field * @param field name of the field which will be returned * @return new instance of the VarField */ public static VarField field(Expression owner, String field) { return new VarField(owner, field); } /** * Sets value to the field in owner * * @param owner owner of the field * @param field name of field which will be changed * @param value new value for the field * @return new instance of the ExpressionSet */ public static Expression set(Expression owner, String field, Expression value) { return set(field(owner, field), value); } /** * Returns current instance * * @return current instance of the Expression */ public static Expression self() { return new VarThis(); } /** * Returns value which ordinal number is 'argument' * * @param argument ordinal number in list of arguments * @return new instance of the VarArg */ public static VarArg arg(int argument) { return new VarArg(argument); } public static PredicateDef alwaysFalse() { return new PredicateDefConst(false); } public static PredicateDef alwaysTrue() { return new PredicateDefConst(true); } public static PredicateDef not(PredicateDef predicateDef) { return new PredicateDefNot(predicateDef); } /** * Compares arguments * * @param eq operation which will be used for the arguments * @param left first argument which will be compared * @param right second argument which will be compared * @return new instance of the PredicateDefCmp */ public static PredicateDefCmp cmp(PredicateDefCmp.Operation eq, Expression left, Expression right) { return PredicateDefCmp.create(eq, left, right); } /** * Verifies that the arguments are equal * * @param left first argument which will be compared * @param right second argument which will be compared * @return new instance of the PredicateDefCmp */ public static PredicateDefCmp cmpEq(Expression left, Expression right) { return cmp(PredicateDefCmp.Operation.EQ, left, right); } public static PredicateDefCmp cmpGe(Expression left, Expression right) { return cmp(PredicateDefCmp.Operation.GE, left, right); } public static PredicateDefCmp cmpLe(Expression left, Expression right) { return cmp(PredicateDefCmp.Operation.LE, left, right); } public static PredicateDefCmp cmpLt(Expression left, Expression right) { return cmp(PredicateDefCmp.Operation.LT, left, right); } public static PredicateDefCmp cmpNe(Expression left, Expression right) { return cmp(PredicateDefCmp.Operation.NE, left, right); } /** * Returns result of logical 'and' for the list of predicates * * @param predicateDefs list of the predicate * @return new instance of the PredicateDefAnd */ public static PredicateDefAnd and(List<PredicateDef> predicateDefs) { return PredicateDefAnd.create(predicateDefs); } /** * Returns result of logical 'and' for the list of predicates * * @param predicateDefs list of the predicate * @return new instance of the PredicateDefAnd */ public static PredicateDefAnd and(PredicateDef... predicateDefs) { return and(asList(predicateDefs)); } /** * Returns result of logical 'or' for the list of predicates * * @param predicateDefs list of the predicate * @return new instance of the PredicateDefOr */ public static PredicateDefOr or(List<PredicateDef> predicateDefs) { return PredicateDefOr.create(predicateDefs); } /** * Returns result of logical 'or' for the list of predicates * * @param predicateDefs list of the predicate * @return new instance of the PredicateDefAnd */ public static PredicateDefOr or(PredicateDef... predicateDefs) { return or(asList(predicateDefs)); } /** * Verifies that the fields are equal * * @param fields list of the fields * @return new instance of the Expression */ public static Expression asEquals(List<String> fields) { PredicateDefAnd predicate = and(); for (String field : fields) { predicate.add(cmpEq( field(self(), field), field(cast(arg(0), ExpressionCast.THIS_TYPE), field))); } return predicate; } /** * Returns the string which was constructed from fields * * @param fields list of the fields * @return new instance of the ExpressionToString */ public static ExpressionToString asString(List<String> fields) { ExpressionToString toString = new ExpressionToString(); for (String field : fields) { toString.withArgument(field + "=", field(self(), field)); } return toString; } /** * Returns the string which was constructed from fields * * @param fields list of the fields * @return new instance of the ExpressionToString */ public static ExpressionToString asString(String... fields) { return asString(asList(fields)); } /** * Verifies that the fields are equal * * @param fields list of the fields * @return new instance of the Expression */ public static Expression asEquals(String... fields) { return asEquals(asList(fields)); } /** * Compares the fields * * @param type type of the fields * @param fields fields which will be compared * @return new instance of the ExpressionComparator */ public static ExpressionComparator compare(Class<?> type, List<String> fields) { ExpressionComparator comparator = ExpressionComparator.create(); for (String field : fields) { comparator = comparator.with(leftField(type, field), rightField(type, field), true); } return comparator; } /** * Compares the fields * * @param type type of the fields * @param fields fields which will be compared * @return new instance of the ExpressionComparator */ public static ExpressionComparator compare(Class<?> type, String... fields) { return compare(type, asList(fields)); } /** * Compares the fields * * @param fields list of the fields with will be compared * @return new instance of the ExpressionComparator */ public static ExpressionComparator compareTo(List<String> fields) { ExpressionComparator comparator = ExpressionComparator.create(); for (String field : fields) { comparator = comparator.with(thisField(field), thatField(field), true); } return comparator; } /** * Compares the fields * * @param fields list of the fields with will be compared * @return new instance of the ExpressionComparator */ public static ExpressionComparator compareTo(String... fields) { return compareTo(asList(fields)); } /** * Returns new constant for the value * * @param value value which will be created as constant * @return new instance of the ExpressionConstant */ public static ExpressionConstant value(Object value) { return new ExpressionConstant(value); } /** * Returns hash of the fields * * @param fields list of the fields which will be hashed * @return new instance of the ExpressionHash */ public static ExpressionHash hashCodeOfThis(List<String> fields) { List<Expression> arguments = new ArrayList<>(); for (String field : fields) { arguments.add(field(new VarThis(), field)); } return new ExpressionHash(arguments); } public static ExpressionHash hashCodeOfThis(String... fields) { return hashCodeOfThis(asList(fields)); } /** * Returns a hash code which calculated from fields * * @param fields list of the fields which will be hashed * @return new instance of the ExpressionHash */ public static ExpressionHash hashCodeOfArgs(List<Expression> fields) { return new ExpressionHash(fields); } /** * Returns a hash code which calculated from fields * * @param fields list of the fields which will be hashed * @return new instance of the ExpressionHash */ public static ExpressionHash hashCodeOfArgs(Expression... fields) { return hashCodeOfArgs(asList(fields)); } public static Class<?> unifyArithmeticTypes(Class<?>... types) { return ExpressionArithmeticOp.unifyArithmeticTypes(types); } public static Class<?> unifyArithmeticTypes(List<Class<?>> types) { return ExpressionArithmeticOp.unifyArithmeticTypes(types.toArray(new Class[types.size()])); } public static ExpressionArithmeticOp arithmeticOp(ExpressionArithmeticOp.Operation op, Expression left, Expression right) { return new ExpressionArithmeticOp(op, left, right); } /** * Returns sum of arguments * * @param left first argument whick will be added * @param right second argument which will be added * @return new instance of the ExpressionArithmeticOp */ public static ExpressionArithmeticOp add(Expression left, Expression right) { return new ExpressionArithmeticOp(ExpressionArithmeticOp.Operation.ADD, left, right); } public static ExpressionArithmeticOp inc(Expression value) { return new ExpressionArithmeticOp(ExpressionArithmeticOp.Operation.ADD, value, value(1)); } public static ExpressionArithmeticOp sub(Expression left, Expression right) { return new ExpressionArithmeticOp(ExpressionArithmeticOp.Operation.SUB, left, right); } public static ExpressionArithmeticOp dec(Expression value) { return new ExpressionArithmeticOp(ExpressionArithmeticOp.Operation.SUB, value, value(1)); } public static ExpressionArithmeticOp mul(Expression left, Expression right) { return new ExpressionArithmeticOp(ExpressionArithmeticOp.Operation.MUL, left, right); } public static ExpressionArithmeticOp div(Expression left, Expression right) { return new ExpressionArithmeticOp(ExpressionArithmeticOp.Operation.DIV, left, right); } public static ExpressionArithmeticOp rem(Expression left, Expression right) { return new ExpressionArithmeticOp(ExpressionArithmeticOp.Operation.REM, left, right); } /** * Returns new instance of class * * @param type type of the constructor * @param fields fields for constructor * @return new instance of the ExpressionConstructor */ public static ExpressionConstructor constructor(Class<?> type, Expression... fields) { return new ExpressionConstructor(type, fields); } /** * Calls method which defines static in the class * * @param owner owner of the method * @param methodName name of the method in the class * @param arguments list of the arguments for the method * @return new instance of the ExpressionCall */ public static Expression call(Expression owner, String methodName, Expression... arguments) { return new ExpressionCall(owner, methodName, arguments); } public static Expression ifThenElse(PredicateDef condition, Expression left, Expression right) { return new ExpressionIf(condition, left, right); } public static Expression length(Expression field) { return new ExpressionLength(field); } public static Expression newArray(Class<?> type, Expression length) { return new ExpressionNewArray(type, length); } public static Expression callStatic(Class<?> owner, String method, Expression... arguments) { return new ExpressionCallStatic(owner, method, arguments); } public static Expression callStaticSelf(String method, Expression... arguments) { return new ExpressionCallStaticSelf(method, arguments); } public static Expression getArrayItem(Expression array, Expression nom) { return new ExpressionArrayGet(array, nom); } public static PredicateDef isNull(Expression field) { return new ExpressionCmpNull(field); } public static PredicateDef isNotNull(Expression field) { return new ExpressionCmpNotNull(field); } public static Expression nullRef(Class<?> type) { return new ExpressionNull(type); } public static Expression nullRef(Type type) { return new ExpressionNull(type); } public static Expression voidExp() { return ExpressionVoid.instance; } public static Expression switchForPosition(Expression position, List<Expression> list) { return new ExpressionSwitch(position, list); } public static Expression switchForPosition(Expression position, Expression... expressions) { return new ExpressionSwitch(position, asList(expressions)); } public static Expression switchForPosition(Expression position, Expression defaultExp, List<Expression> list) { return new ExpressionSwitch(position, defaultExp, list); } public static Expression switchForPosition(Expression position, Expression defaultExp, Expression... expressions) { return new ExpressionSwitch(position, defaultExp, asList(expressions)); } public static Expression switchForKey(Expression key, List<Expression> listKey, List<Expression> listValue) { return new ExpressionSwitchForKey(key, listKey, listValue); } public static Expression switchForKey(Expression key, Expression defaultExp, List<Expression> listKey, List<Expression> listValue) { return new ExpressionSwitchForKey(key, listKey, listValue); } public static Expression setArrayItem(Expression array, Expression position, Expression newElement) { return new ExpressionArraySet(array, position, newElement); } public static Expression expressionFor(Expression start, Expression length, ForVar forVar) { return new ExpressionFor(start, length, forVar); } public static Expression expressionFor(Expression length, ForVar forVar) { return new ExpressionFor(length, forVar); } public static Expression mapForEach(Expression field, ForVar forKey, ForVar forValue) { return new ExpressionMapForEach(field, forKey, forValue); } public static Expression hppcMapForEach(Class<?> iteratorType, Expression value, ForVar forKey, ForVar forValue) { return new ForEachHppcMap(iteratorType, value, forKey, forValue); } public static Expression hppcSetForEach(Class<?> iteratorType, Expression field, ForVar forVar) { return new ForEachHppcSet(iteratorType, field, forVar); } public static Expression neg(Expression arg) { return new ExpressionNeg(arg); } public static Expression bitOp(ExpressionBitOp.Operation op, Expression value, Expression shift) { return new ExpressionBitOp(op, value, shift); } public static Expression setListItem(Expression list, Expression position, Expression value) { return call(list, "set", position, value); } public static Expression getListItem(Expression list, Expression position) { return call(list, "get", position); } public static Expression addListItem(Expression list, Expression value) { return call(list, "add", value); } public static Expression forEach(Expression collection, ForVar forCollection) { return new ExpressionIteratorForEach(collection, forCollection); } public static Expression forEach(Expression collection, Class<?> type, ForVar forCollection) { return new ExpressionIteratorForEach(collection, type, forCollection); } }