blob: ca2bcdc5214ac38d175064a2e6c2144e8c335f0e [file] [log] [blame]
/*
// Licensed to Julian Hyde under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// Julian Hyde licenses this file to you 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 net.hydromatic.linq4j.expressions;
import net.hydromatic.linq4j.Extensions;
import net.hydromatic.linq4j.function.*;
import java.lang.reflect.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
/**
* Utility methods for expressions, including a lot of factory methods.
*/
public class Expressions {
/**
* Converts a list of expressions to Java source code, optionally emitting
* extra type information in generics.
*/
public static String toString(List<? extends Node> expressions, String sep,
boolean generics) {
final ExpressionWriter writer = new ExpressionWriter(generics);
for (Node expression : expressions) {
writer.write(expression);
writer.append(sep);
}
return writer.toString();
}
/**
* Converts an expression to Java source code.
*/
public static String toString(Node expression) {
return toString(Collections.singletonList(expression), "", true);
}
/**
* Creates a BinaryExpression that represents an arithmetic
* addition operation that does not have overflow checking.
*/
public static BinaryExpression add(Expression left, Expression right) {
return makeBinary(ExpressionType.Add, left, right);
}
/**
* Creates a BinaryExpression that represents an arithmetic
* addition operation that does not have overflow checking. The
* implementing method can be specified.
*/
public static BinaryExpression add(Expression left, Expression right,
Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents an addition
* assignment operation that does not have overflow checking.
*/
public static BinaryExpression addAssign(Expression left, Expression right) {
return makeBinary(ExpressionType.AddAssign, left, right);
}
/**
* Creates a BinaryExpression that represents an addition
* assignment operation that does not have overflow checking.
*/
public static BinaryExpression addAssign(Expression left, Expression right,
Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents an addition
* assignment operation that does not have overflow checking.
*/
public static BinaryExpression addAssign(Expression left, Expression right,
Method method, LambdaExpression lambdaLeft,
LambdaExpression lambdaRight) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents an addition
* assignment operation that has overflow checking.
*/
public static BinaryExpression addAssignChecked(Expression left,
Expression right) {
return makeBinary(ExpressionType.AddAssignChecked, left, right);
}
/**
* Creates a BinaryExpression that represents an addition
* assignment operation that has overflow checking.
*/
public static BinaryExpression addAssignChecked(Expression left,
Expression right, Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents an addition
* assignment operation that has overflow checking.
*/
public static BinaryExpression addAssignChecked(Expression left,
Expression right, Method method, LambdaExpression lambdaExpression) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents an arithmetic
* addition operation that has overflow checking.
*/
public static BinaryExpression addChecked(Expression left, Expression right) {
return makeBinary(ExpressionType.AddChecked, left, right);
}
/**
* Creates a BinaryExpression that represents an arithmetic
* addition operation that has overflow checking. The implementing
* method can be specified.
*/
public static BinaryExpression addChecked(Expression left, Expression right,
Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a bitwise AND
* operation.
*/
public static BinaryExpression and(Expression left, Expression right) {
return makeBinary(ExpressionType.And, left, right);
}
/**
* Creates a BinaryExpression that represents a bitwise AND
* operation. The implementing method can be specified.
*/
public static BinaryExpression and(Expression left, Expression right,
Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a conditional AND
* operation that evaluates the second operand only if the first
* operand evaluates to true.
*/
public static BinaryExpression andAlso(Expression left, Expression right) {
return makeBinary(ExpressionType.AndAlso, left, right);
}
/**
* Creates a BinaryExpression that represents a conditional AND
* operation that evaluates the second operand only if the first
* operand is resolved to true. The implementing method can be
* specified.
*/
public static BinaryExpression andAlso(Expression left, Expression right,
Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a bitwise AND
* assignment operation.
*/
public static BinaryExpression andAssign(Expression left, Expression right) {
return makeBinary(ExpressionType.AndAssign, left, right);
}
/**
* Creates a BinaryExpression that represents a bitwise AND
* assignment operation.
*/
public static BinaryExpression andAssign(Expression left, Expression right,
Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a bitwise AND
* assignment operation.
*/
public static BinaryExpression andAssign(Expression left, Expression right,
Method method, LambdaExpression lambdaExpression) {
throw Extensions.todo();
}
/**
* Creates an expression that represents applying an array
* index operator to an array of rank one.
*/
public static IndexExpression arrayIndex(Expression array,
Expression indexExpression) {
return new IndexExpression(array,
Collections.singletonList(indexExpression));
}
/**
* Creates a UnaryExpression that represents an expression for
* obtaining the length of a one-dimensional array.
*/
public static UnaryExpression arrayLength(Expression array) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents an assignment
* operation.
*/
public static BinaryExpression assign(Expression left, Expression right) {
return makeBinary(ExpressionType.Assign, left, right);
}
/**
* Creates a MemberAssignment that represents the initialization
* of a field or property.
*/
public static MemberAssignment bind(Member member, Expression right) {
throw Extensions.todo();
}
/**
* Creates a MemberAssignment that represents the initialization
* of a member by using a property accessor method.
*/
public static MemberAssignment bind(Method method, Expression expression) {
throw Extensions.todo();
}
/**
* Creates a BlockExpression that contains the given statements.
*/
public static BlockStatement block(
Iterable<? extends Statement> statements) {
return block((Type) null, statements);
}
/**
* Creates a BlockExpression that contains the given statements,
* using varargs.
*/
public static BlockStatement block(Statement... statements) {
return block(toList(statements));
}
/**
* Creates a BlockExpression that contains the given expressions,
* has no variables and has specific result type.
*/
public static BlockStatement block(Type type,
Iterable<? extends Statement> expressions) {
List<Statement> list = toList(expressions);
if (type == null) {
if (list.size() > 0) {
type = list.get(list.size() - 1).getType();
} else {
type = Void.TYPE;
}
}
return new BlockStatement(list, type);
}
/**
* Creates a BlockExpression that contains the given statements
* and has a specific result type, using varargs.
*/
public static BlockStatement block(Type type, Statement... statements) {
return block(type, toList(statements));
}
/**
* Creates a GotoExpression representing a break statement.
*/
public static GotoStatement break_(LabelTarget labelTarget) {
return new GotoStatement(GotoExpressionKind.Break, null, null);
}
/**
* Creates a GotoExpression representing a break statement. The
* value passed to the label upon jumping can be specified.
*/
public static GotoStatement break_(LabelTarget labelTarget,
Expression expression) {
return new GotoStatement(GotoExpressionKind.Break, null, expression);
}
/**
* Creates a GotoExpression representing a break statement with
* the specified type.
*/
public static GotoStatement break_(LabelTarget labelTarget, Type type) {
throw Extensions.todo();
}
/**
* Creates a GotoExpression representing a break statement with
* the specified type. The value passed to the label upon jumping
* can be specified.
*/
public static GotoStatement break_(LabelTarget labelTarget,
Expression expression, Type type) {
throw Extensions.todo();
}
/**
* Creates a MethodCallExpression that represents a call to a
* static method that has arguments.
*/
public static MethodCallExpression call(Method method,
Iterable<? extends Expression> arguments) {
return new MethodCallExpression(method, null, toList(arguments));
}
/**
* Creates a MethodCallExpression that represents a call to a
* static method that has arguments, using varargs.
*/
public static MethodCallExpression call(Method method,
Expression... arguments) {
return new MethodCallExpression(method, null, toList(arguments));
}
/**
* Creates a MethodCallExpression that represents a call to a
* method that takes arguments.
*/
public static MethodCallExpression call(Expression expression, Method method,
Iterable<? extends Expression> arguments) {
return new MethodCallExpression(method, expression, toList(arguments));
}
/**
* Creates a MethodCallExpression that represents a call to a
* method that takes arguments, using varargs.
*/
public static MethodCallExpression call(Expression expression, Method method,
Expression... arguments) {
return new MethodCallExpression(method, expression, toList(arguments));
}
/**
* Creates a MethodCallExpression that represents a call to a
* method that takes arguments, with an explicit return type.
*
* <p>The return type must be consistent with the return type of the method,
* but may contain extra information, such as type parameters.</p>
*
* <p>The {@code expression} argument may be null if and only if the method
* is static.</p>
*/
public static MethodCallExpression call(Type returnType,
Expression expression, Method method,
Iterable<? extends Expression> arguments) {
return new MethodCallExpression(returnType, method, expression,
toList(arguments));
}
/**
* Creates a MethodCallExpression that represents a call to a
* method that takes arguments, with an explicit return type, with varargs.
*
* <p>The return type must be consistent with the return type of the method,
* but may contain extra information, such as type parameters.</p>
*
* <p>The {@code expression} argument may be null if and only if the method
* is static.</p>
*/
public static MethodCallExpression call(Type returnType,
Expression expression, Method method,
Expression... arguments) {
return new MethodCallExpression(returnType, method, expression,
toList(arguments));
}
/**
* Creates a MethodCallExpression that represents a call to an
* instance method by calling the appropriate factory method.
*/
public static MethodCallExpression call(Expression target, String methodName,
Iterable<? extends Expression> arguments) {
Method method;
try {
//noinspection unchecked
method = Types.toClass(target.getType())
.getMethod(methodName, Types.toClassArray(arguments));
} catch (NoSuchMethodException e) {
throw new RuntimeException("while resolving method '" + methodName
+ "' in class " + target.getType(), e);
}
return call(target, method, arguments);
}
/**
* Creates a MethodCallExpression that represents a call to an
* instance method by calling the appropriate factory method, using varargs.
*/
public static MethodCallExpression call(Expression target, String methodName,
Expression... arguments) {
return call(target, methodName, toList(arguments));
}
/**
* Creates a MethodCallExpression that represents a call to a
* static method by calling the
* appropriate factory method.
*/
public static MethodCallExpression call(Type type, String methodName,
Iterable<? extends Expression> arguments) {
Method method = Types.lookupMethod(Types.toClass(type), methodName,
Types.toClassArray(arguments));
return new MethodCallExpression(method, null, toList(arguments));
}
/**
* Creates a MethodCallExpression that represents a call to a
* static method by calling the
* appropriate factory method, using varargs.
*/
public static MethodCallExpression call(Type type, String methodName,
Expression... arguments) {
return call(type, methodName, toList(arguments));
}
/**
* Creates a CatchBlock representing a catch statement with a
* reference to the caught Exception object for use in the handler
* body.
*/
public static CatchBlock catch_(ParameterExpression expression0,
Expression expression1) {
throw Extensions.todo();
}
/**
* Creates a CatchBlock representing a catch statement.
*/
public static CatchBlock catch_(Type type, Expression expression) {
throw Extensions.todo();
}
/**
* Creates a CatchBlock representing a catch statement with an
* Exception filter and a reference to the caught Exception
* object.
*/
public static CatchBlock catch_(ParameterExpression expression0,
Expression expression1, Expression expression2) {
throw Extensions.todo();
}
/**
* Creates a CatchBlock representing a catch statement with an
* Exception filter but no reference to the caught Exception
* object.
*/
public static CatchBlock catch_(Type type, Expression expression0,
Expression expression1) {
throw Extensions.todo();
}
/**
* Creates a DebugInfoExpression for clearing a sequence
* point.
*/
public static void clearDebugInfo() {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a coalescing
* operation.
*/
public static BinaryExpression coalesce(Expression left, Expression right) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a coalescing
* operation, given a conversion function.
*/
public static BinaryExpression coalesce(Expression left, Expression right,
LambdaExpression lambdaExpression) {
throw Extensions.todo();
}
/**
* Creates a ConditionalExpression that represents a conditional
* statement.
*/
public static Expression condition(Expression test, Expression ifTrue,
Expression ifFalse) {
return makeTernary(ExpressionType.Conditional, test, ifTrue, ifFalse);
}
private static Type box(Type type) {
Primitive primitive = Primitive.of(type);
if (primitive != null) {
return primitive.boxClass;
}
return type;
}
/** Returns whether an expression always evaluates to null. */
public static boolean isConstantNull(Expression e) {
return e instanceof ConstantExpression
&& ((ConstantExpression) e).value == null;
}
/**
* Creates a ConditionalExpression that represents a conditional
* statement.
*
* <p>This method allows explicitly unifying the result type of the
* conditional expression in cases where the types of ifTrue and ifFalse
* expressions are not equal. Types of both ifTrue and ifFalse must be
* implicitly reference assignable to the result type. The type is allowed
* to be {@link Void#TYPE void}.</p>
*/
public static ConditionalExpression condition(Expression test,
Expression ifTrue, Expression ifFalse, Type type) {
return new ConditionalExpression(Arrays.<Node>asList(test, ifFalse, ifTrue),
type);
}
/**
* Creates a ConstantExpression that has the Value property set
* to the specified value.
*
* <p>Does the right thing for null, String, primitive values (e.g. int 12,
* short 12, double 3.14 and boolean false), boxed primitives
* (e.g. Integer.valueOf(12)), enums, classes, BigDecimal, BigInteger,
* classes that have a constructor with a parameter for each field, and
* arrays.</p>
*/
public static ConstantExpression constant(Object value) {
Class type;
if (value == null) {
type = Object.class;
} else {
final Class clazz = value.getClass();
final Primitive primitive = Primitive.ofBox(clazz);
if (primitive != null) {
type = primitive.primitiveClass;
} else {
type = clazz;
}
}
return new ConstantExpression(type, value);
}
/**
* Creates a ConstantExpression that has the Value and Type
* properties set to the specified values.
*/
public static ConstantExpression constant(Object value, Type type) {
if (value != null && type instanceof Class) {
// Fix up value so that it matches type.
Class clazz = (Class) type;
Primitive primitive = Primitive.ofBoxOr(clazz);
if (primitive != null) {
clazz = primitive.boxClass;
}
if (!clazz.isInstance(value)) {
String stringValue = String.valueOf(value);
if (type == BigDecimal.class) {
value = new BigDecimal(stringValue);
}
if (type == BigInteger.class) {
value = new BigInteger(stringValue);
}
if (primitive != null) {
value = primitive.parse(stringValue);
}
}
}
return new ConstantExpression(type, value);
}
/**
* Creates a GotoExpression representing a continue statement.
*/
public static GotoStatement continue_(LabelTarget labelTarget) {
throw Extensions.todo();
}
/**
* Creates a GotoExpression representing a continue statement
* with the specified type.
*/
public static GotoStatement continue_(LabelTarget labelTarget, Type type) {
throw Extensions.todo();
}
/**
* Creates a UnaryExpression that represents a type conversion
* operation.
*/
public static UnaryExpression convert_(Expression expression, Type type) {
return new UnaryExpression(ExpressionType.Convert, type, expression);
}
/**
* Creates a UnaryExpression that represents a conversion
* operation for which the implementing method is specified.
*/
public static UnaryExpression convert_(Expression expression, Type type,
Method method) {
throw Extensions.todo();
}
/**
* Creates a UnaryExpression that represents a conversion
* operation that throws an exception if the target type is
* overflowed.
*/
public static UnaryExpression convertChecked(Expression expression,
Type type) {
throw Extensions.todo();
}
/**
* Creates a UnaryExpression that represents a conversion
* operation that throws an exception if the target type is
* overflowed and for which the implementing method is
* specified.
*/
public static UnaryExpression convertChecked_(Expression expression,
Type type, Method method) {
throw Extensions.todo();
}
/**
* Creates a DebugInfoExpression with the specified span.
*/
public static void debugInfo() {
throw Extensions.todo();
}
/**
* Creates a UnaryExpression that represents the decrementing of
* the expression by 1.
*/
public static UnaryExpression decrement(Expression expression) {
throw Extensions.todo();
}
/**
* Creates a UnaryExpression that represents the decrementing of
* the expression by 1.
*/
public static UnaryExpression decrement(Expression expression,
Method method) {
throw Extensions.todo();
}
/**
* Creates a DefaultExpression that has the Type property set to
* the specified type.
*/
public static DefaultExpression default_() {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents an arithmetic
* division operation.
*/
public static BinaryExpression divide(Expression left, Expression right) {
return makeBinary(ExpressionType.Divide, left, right);
}
/**
* Creates a BinaryExpression that represents an arithmetic
* division operation. The implementing method can be
* specified.
*/
public static BinaryExpression divide(Expression left, Expression right,
Method method) {
return makeBinary(ExpressionType.Divide, left, right, shouldLift(left,
right, method), method);
}
/**
* Creates a BinaryExpression that represents a division
* assignment operation that does not have overflow checking.
*/
public static BinaryExpression divideAssign(Expression left,
Expression right) {
return makeBinary(ExpressionType.DivideAssign, left, right);
}
/**
* Creates a BinaryExpression that represents a division
* assignment operation that does not have overflow checking.
*/
public static BinaryExpression divideAssign(Expression left, Expression right,
Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a division
* assignment operation that does not have overflow checking.
*/
public static BinaryExpression divideAssign(Expression left, Expression right,
Method method, LambdaExpression lambdaExpression) {
throw Extensions.todo();
}
/**
* Creates a DynamicExpression that represents a dynamic
* operation bound by the provided CallSiteBinder.
*/
public static DynamicExpression dynamic(CallSiteBinder binder, Type type,
Iterable<? extends Expression> expressions) {
throw Extensions.todo();
}
/**
* Creates a DynamicExpression that represents a dynamic
* operation bound by the provided CallSiteBinder, using varargs.
*/
public static DynamicExpression dynamic(CallSiteBinder binder, Type type,
Expression... expression) {
throw Extensions.todo();
}
/**
* Creates an ElementInit, given an Iterable<T> as the second
* argument.
*/
public static ElementInit elementInit(Method method,
Iterable<? extends Expression> expressions) {
throw Extensions.todo();
}
/**
* Creates an ElementInit, given an array of values as the second
* argument, using varargs.
*/
public static ElementInit elementInit(Method method,
Expression... expressions) {
throw Extensions.todo();
}
/**
* Creates an empty expression that has Void type.
*/
public static DefaultExpression empty() {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents an equality
* comparison.
*/
public static BinaryExpression equal(Expression left, Expression right) {
return makeBinary(ExpressionType.Equal, left, right);
}
/**
* Creates a BinaryExpression that represents an equality
* comparison. The implementing method can be specified.
*/
public static BinaryExpression equal(Expression expression0,
Expression expression1, boolean liftToNull, Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a bitwise XOR
* operation, using op_ExclusiveOr for user-defined types.
*/
public static BinaryExpression exclusiveOr(Expression left,
Expression right) {
return makeBinary(ExpressionType.ExclusiveOr, left, right);
}
/**
* Creates a BinaryExpression that represents a bitwise XOR
* operation, using op_ExclusiveOr for user-defined types. The
* implementing method can be specified.
*/
public static BinaryExpression exclusiveOr(Expression left, Expression right,
Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a bitwise XOR
* assignment operation, using op_ExclusiveOr for user-defined
* types.
*/
public static BinaryExpression exclusiveOrAssign(Expression left,
Expression right) {
return makeBinary(ExpressionType.ExclusiveOrAssign, left, right);
}
/**
* Creates a BinaryExpression that represents a bitwise XOR
* assignment operation, using op_ExclusiveOr for user-defined
* types.
*/
public static BinaryExpression exclusiveOrAssign(Expression left,
Expression right, Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a bitwise XOR
* assignment operation, using op_ExclusiveOr for user-defined
* types.
*/
public static BinaryExpression exclusiveOrAssign(Expression left,
Expression right, Method method, LambdaExpression lambdaExpression) {
throw Extensions.todo();
}
/**
* Creates a MemberExpression that represents accessing a field.
*/
public static MemberExpression field(Expression expression, Field field) {
return makeMemberAccess(expression, Types.field(field));
}
/**
* Creates a MemberExpression that represents accessing a field.
*/
public static MemberExpression field(Expression expression,
PseudoField field) {
return makeMemberAccess(expression, field);
}
/**
* Creates a MemberExpression that represents accessing a field
* given the name of the field.
*/
public static MemberExpression field(Expression expression,
String fieldName) {
PseudoField field = Types.getField(fieldName, expression.getType());
return makeMemberAccess(expression, field);
}
/**
* Creates a MemberExpression that represents accessing a field.
*/
public static MemberExpression field(Expression expression, Type type,
String fieldName) {
PseudoField field = Types.getField(fieldName, type);
return makeMemberAccess(expression, field);
}
/**
* Creates a Type object that represents a generic System.Action
* delegate type that has specific type arguments.
*/
public static Class getActionType(Class... typeArgs) {
throw Extensions.todo();
}
/**
* Gets a Type object that represents a generic System.Func or
* System.Action delegate type that has specific type
* arguments.
*/
public static Class getDelegateType(Class... typeArgs) {
throw Extensions.todo();
}
/**
* Creates a Type object that represents a generic System.Func
* delegate type that has specific type arguments. The last type
* argument specifies the return type of the created delegate.
*/
public static Class getFuncType(Class... typeArgs) {
throw Extensions.todo();
}
/**
* Creates a GotoExpression representing a "go to" statement.
*/
public static GotoStatement goto_(LabelTarget labelTarget) {
throw Extensions.todo();
}
/**
* Creates a GotoExpression representing a "go to" statement. The
* value passed to the label upon jumping can be specified.
*/
public static GotoStatement goto_(LabelTarget labelTarget,
Expression expression) {
throw Extensions.todo();
}
/**
* Creates a GotoExpression representing a "go to" statement with
* the specified type.
*/
public static GotoStatement goto_(LabelTarget labelTarget, Type type) {
throw Extensions.todo();
}
/**
* Creates a GotoExpression representing a "go to" statement with
* the specified type. The value passed to the label upon jumping
* can be specified.
*/
public static GotoStatement goto_(LabelTarget labelTarget,
Expression expression, Type type) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a "greater than"
* numeric comparison.
*/
public static BinaryExpression greaterThan(Expression left,
Expression right) {
return makeBinary(ExpressionType.GreaterThan, left, right);
}
/**
* Creates a BinaryExpression that represents a "greater than"
* numeric comparison. The implementing method can be
* specified.
*/
public static BinaryExpression greaterThan(Expression left, Expression right,
boolean liftToNull, Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a "greater than or
* equal" numeric comparison.
*/
public static BinaryExpression greaterThanOrEqual(Expression left,
Expression right) {
return makeBinary(ExpressionType.GreaterThanOrEqual, left, right);
}
/**
* Creates a BinaryExpression that represents a "greater than or
* equal" numeric comparison.
*/
public static BinaryExpression greaterThanOrEqual(Expression left,
Expression right, boolean liftToNull, Method method) {
throw Extensions.todo();
}
/**
* Creates a ConditionalExpression that represents a conditional
* block with an if statement.
*/
public static ConditionalStatement ifThen(Expression test, Node ifTrue) {
return new ConditionalStatement(Arrays.<Node>asList(test, ifTrue));
}
/**
* Creates a ConditionalExpression that represents a conditional
* block with if and else statements.
*/
public static ConditionalStatement ifThenElse(Expression test, Node ifTrue,
Node ifFalse) {
return new ConditionalStatement(Arrays.<Node>asList(test, ifTrue, ifFalse));
}
/**
* Creates a UnaryExpression that represents the incrementing of
* the expression value by 1.
*/
public static UnaryExpression increment(Expression expression) {
throw Extensions.todo();
}
/**
* Creates a UnaryExpression that represents the incrementing of
* the expression by 1.
*/
public static UnaryExpression increment(Expression expression,
Method method) {
throw Extensions.todo();
}
/**
* Creates an InvocationExpression that applies a delegate or
* lambda expression to a list of argument expressions.
*/
public static InvocationExpression invoke(Expression expression,
Iterable<? extends Expression> arguments) {
throw Extensions.todo();
}
/**
* Creates an InvocationExpression that applies a delegate or
* lambda expression to a list of argument expressions, using varargs.
*/
public static InvocationExpression invoke(Expression expression,
Expression... arguments) {
throw Extensions.todo();
}
/**
* Returns whether the expression evaluates to false.
*/
public static UnaryExpression isFalse(Expression expression) {
throw Extensions.todo();
}
/**
* Returns whether the expression evaluates to false.
*/
public static UnaryExpression isFalse(Expression expression, Method method) {
throw Extensions.todo();
}
/**
* Returns whether the expression evaluates to true.
*/
public static UnaryExpression isTrue(Expression expression) {
throw Extensions.todo();
}
/**
* Returns whether the expression evaluates to true.
*/
public static UnaryExpression isTrue(Expression expression, Method method) {
throw Extensions.todo();
}
/**
* Creates a LabelTarget representing a label with X type and
* no name.
*/
public static LabelTarget label() {
throw Extensions.todo();
}
/**
* Creates a LabelExpression representing a label without a
* default value.
*/
public static LabelStatement label(LabelTarget labelTarget) {
throw Extensions.todo();
}
/**
* Creates a LabelTarget representing a label with X type and
* the given name.
*/
public static LabelTarget label(String name) {
throw Extensions.todo();
}
/**
* Creates a LabelTarget representing a label with the given
* type.
*/
public static LabelTarget label(Type type) {
throw Extensions.todo();
}
/**
* Creates a LabelExpression representing a label with the given
* default value.
*/
public static LabelStatement label(LabelTarget labelTarget,
Expression expression) {
throw Extensions.todo();
}
/**
* Creates a LabelTarget representing a label with the given type
* and name.
*/
public static LabelTarget label(Type type, String name) {
throw Extensions.todo();
}
/**
* Creates a FunctionExpression from an actual function.
*/
public static <F extends Function<?>> FunctionExpression<F> lambda(
F function) {
// REVIEW: Check that that function class is non-inner, has a public
// default constructor, etc.?
//noinspection unchecked
return new FunctionExpression<F>(function);
}
/**
* Creates a LambdaExpression by first constructing a delegate
* type.
*/
public static <F extends Function<?>> FunctionExpression<F> lambda(
BlockStatement body,
Iterable<? extends ParameterExpression> parameters) {
final List<ParameterExpression> parameterList = toList(parameters);
@SuppressWarnings("unchecked")
Class<F> type = deduceType(parameterList, body.getType());
return new FunctionExpression<F>(type, body, parameterList);
}
/**
* Creates a LambdaExpression by first constructing a delegate
* type, using varargs.
*/
public static <F extends Function<?>> FunctionExpression<F> lambda(
BlockStatement body, ParameterExpression... parameters) {
return lambda(body, toList(parameters));
}
/**
* Creates an Expression where the delegate type {@code F} is
* known at compile time.
*/
public static <F extends Function<?>> FunctionExpression<F> lambda(
Expression body, Iterable<? extends ParameterExpression> parameters) {
return lambda(Blocks.toFunctionBlock(body), parameters);
}
/**
* Creates an Expression where the delegate type {@code F} is
* known at compile time, using varargs.
*/
public static <F extends Function<?>> FunctionExpression<F> lambda(
Expression body, ParameterExpression... parameters) {
return lambda(Blocks.toFunctionBlock(body), toList(parameters));
}
/**
* Creates a LambdaExpression by first constructing a delegate
* type.
*
* <p>It can be used when the delegate type is not known at compile time.
*/
public static <T, F extends Function<? extends T>> FunctionExpression<F>
lambda(Class<F> type, BlockStatement body,
Iterable<? extends ParameterExpression> parameters) {
return new FunctionExpression<F>(type, body, toList(parameters));
}
/**
* Creates a LambdaExpression by first constructing a delegate
* type, using varargs.
*
* <p>It can be used when the delegate type is not known at compile time.
*/
public static <T, F extends Function<? extends T>> FunctionExpression<F>
lambda(Class<F> type, BlockStatement body,
ParameterExpression... parameters) {
return lambda(type, body, toList(parameters));
}
/**
* Creates a LambdaExpression by first constructing a delegate
* type.
*
* <p>It can be used when the delegate type is not known at compile time.
*/
public static <T, F extends Function<? extends T>> FunctionExpression<F>
lambda(Class<F> type, Expression body,
Iterable<? extends ParameterExpression> parameters) {
return lambda(type, Blocks.toFunctionBlock(body), toList(parameters));
}
/**
* Creates a LambdaExpression by first constructing a delegate
* type, using varargs.
*
* <p>It can be used when the delegate type is not known at compile time.
*/
public static <T, F extends Function<? extends T>> FunctionExpression<F>
lambda(Class<F> type, Expression body, ParameterExpression... parameters) {
return lambda(type, Blocks.toFunctionBlock(body), toList(parameters));
}
/**
* Creates a BinaryExpression that represents a bitwise
* left-shift operation.
*/
public static BinaryExpression leftShift(Expression left, Expression right) {
return makeBinary(ExpressionType.LeftShift, left, right);
}
/**
* Creates a BinaryExpression that represents a bitwise
* left-shift operation.
*/
public static BinaryExpression leftShift(Expression left, Expression right,
Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a bitwise
* left-shift assignment operation.
*/
public static BinaryExpression leftShiftAssign(Expression left,
Expression right) {
return makeBinary(ExpressionType.LeftShiftAssign, left, right);
}
/**
* Creates a BinaryExpression that represents a bitwise
* left-shift assignment operation.
*/
public static BinaryExpression leftShiftAssign(Expression left,
Expression right, Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a bitwise
* left-shift assignment operation.
*/
public static BinaryExpression leftShiftAssign(Expression left,
Expression right, Method method, LambdaExpression lambdaExpression) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a "less than"
* numeric comparison.
*/
public static BinaryExpression lessThan(Expression left, Expression right) {
return makeBinary(ExpressionType.LessThan, left, right);
}
/**
* Creates a BinaryExpression that represents a "less than"
* numeric comparison.
*/
public static BinaryExpression lessThan(Expression left, Expression right,
boolean liftToNull, Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a " less than or
* equal" numeric comparison.
*/
public static BinaryExpression lessThanOrEqual(Expression left,
Expression right) {
return makeBinary(ExpressionType.LessThanOrEqual, left, right);
}
/**
* Creates a BinaryExpression that represents a "less than or
* equal" numeric comparison.
*/
public static BinaryExpression lessThanOrEqual(Expression left,
Expression right, boolean liftToNull, Method method) {
throw Extensions.todo();
}
/**
* Creates a MemberListBinding where the member is a field or
* property.
*/
public static MemberListBinding listBind(Member member,
Iterable<? extends ElementInit> elementInits) {
throw Extensions.todo();
}
/**
* Creates a MemberListBinding where the member is a field or
* property, using varargs.
*/
public static MemberListBinding listBind(Member member,
ElementInit... elementInits) {
throw Extensions.todo();
}
/**
* Creates a MemberListBinding based on a specified property
* accessor method.
*/
public static MemberListBinding listBind(Method method,
Iterable<? extends ElementInit> elementInits) {
throw Extensions.todo();
}
/**
* Creates a MemberListBinding object based on a specified
* property accessor method, using varargs.
*/
public static MemberListBinding listBind(Method method,
ElementInit... elementInits) {
throw Extensions.todo();
}
/**
* Creates a ListInitExpression that uses specified ElementInit
* objects to initialize a collection.
*/
public static ListInitExpression listInit(NewExpression newExpression,
Iterable<? extends ElementInit> elementInits) {
throw Extensions.todo();
}
/**
* Creates a ListInitExpression that uses specified ElementInit
* objects to initialize a collection, using varargs.
*/
public static ListInitExpression listInit(NewExpression newExpression,
ElementInit... elementInits) {
throw Extensions.todo();
}
/**
* Creates a ListInitExpression that uses a method named "Add" to
* add elements to a collection.
*/
public static ListInitExpression listInitE(NewExpression newExpression,
Iterable<? extends Expression> arguments) {
throw Extensions.todo();
}
/**
* Creates a ListInitExpression that uses a method named "Add" to
* add elements to a collection, using varargs.
*/
public static ListInitExpression listInit(NewExpression newExpression,
Expression... arguments) {
throw Extensions.todo();
}
/**
* Creates a ListInitExpression that uses a specified method to
* add elements to a collection.
*/
public static ListInitExpression listInit(NewExpression newExpression,
Method method, Iterable<? extends Expression> arguments) {
throw Extensions.todo();
}
/**
* Creates a ListInitExpression that uses a specified method to
* add elements to a collection, using varargs.
*/
public static ListInitExpression listInit(NewExpression newExpression,
Method method, Expression... arguments) {
throw Extensions.todo();
}
/**
* Creates a LoopExpression with the given body.
*/
public static ForStatement for_(
Iterable<? extends DeclarationStatement> declarations,
Expression condition, Expression post, Statement body) {
return new ForStatement(toList(declarations), condition, post, body);
}
/**
* Creates a LoopExpression with the given body.
*/
public static ForStatement for_(
DeclarationStatement declaration,
Expression condition, Expression post, Statement body) {
return new ForStatement(Collections.singletonList(declaration), condition,
post, body);
}
/**
* Creates a BinaryExpression, given the left and right operands,
* by calling an appropriate factory method.
*/
public static BinaryExpression makeBinary(ExpressionType binaryType,
Expression left, Expression right) {
final Type type;
switch (binaryType) {
case Equal:
case NotEqual:
case LessThan:
case LessThanOrEqual:
case GreaterThan:
case GreaterThanOrEqual:
case AndAlso:
case OrElse:
type = Boolean.TYPE;
break;
default:
type = larger(left.type, right.type);
break;
}
return new BinaryExpression(binaryType, type, left, right);
}
/** Returns an expression to box the value of a primitive expression.
* E.g. {@code box(e, Primitive.INT)} returns {@code Integer.valueOf(e)}. */
public static Expression box(Expression expression, Primitive primitive) {
return call(primitive.boxClass, "valueOf", expression);
}
/** Converts e.g. "anInteger" to "Integer.valueOf(anInteger)". */
public static Expression box(Expression expression) {
Primitive primitive = Primitive.of(expression.getType());
if (primitive == null) {
return expression;
}
return box(expression, primitive);
}
/** Returns an expression to unbox the value of a boxed-primitive expression.
* E.g. {@code unbox(e, Primitive.INT)} returns {@code e.intValue()}.
* It is assumed that e is of the right box type (or {@link Number})."Value */
public static Expression unbox(Expression expression, Primitive primitive) {
return call(expression, primitive.primitiveName + "Value");
}
/** Converts e.g. "anInteger" to "anInteger.intValue()". */
public static Expression unbox(Expression expression) {
Primitive primitive = Primitive.ofBox(expression.getType());
if (primitive == null) {
return expression;
}
return unbox(expression, primitive);
}
private Type largest(Type... types) {
Type max = types[0];
for (int i = 1; i < types.length; i++) {
max = larger(max, types[i]);
}
return max;
}
private static Type larger(Type type0, Type type1) {
// curiously, "short + short" has type "int".
// similarly, "byte + byte" has type "int".
// "byte / long" has type "long".
if (type0 == double.class
|| type0 == Double.class
|| type1 == double.class
|| type1 == Double.class) {
return double.class;
}
if (type0 == float.class
|| type0 == Float.class
|| type1 == float.class
|| type1 == Float.class) {
return float.class;
}
if (type0 == long.class
|| type0 == Long.class
|| type1 == long.class
|| type1 == Long.class) {
return long.class;
}
return int.class;
}
/**
* Creates a BinaryExpression, given the left operand, right
* operand and implementing method, by calling the appropriate
* factory method.
*/
public static BinaryExpression makeBinary(ExpressionType binaryType,
Expression left, Expression right, boolean liftToNull, Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression, given the left operand, right
* operand, implementing method and type conversion function, by
* calling the appropriate factory method.
*/
public static BinaryExpression makeBinary(ExpressionType binaryType,
Expression left, Expression right, boolean liftToNull, Method method,
LambdaExpression lambdaExpression) {
throw Extensions.todo();
}
/**
* Creates a TernaryExpression, given the left and right operands,
* by calling an appropriate factory method.
*/
public static TernaryExpression makeTernary(ExpressionType ternaryType,
Expression e0, Expression e1, Expression e2) {
final Type type;
switch (ternaryType) {
case Conditional:
type = isConstantNull(e1)
? box(e2.getType())
: isConstantNull(e2)
? box(e1.getType())
: Types.gcd(e1.getType(), e2.getType());
break;
default:
type = e1.getType();
}
return new TernaryExpression(ternaryType, type, e0, e1, e2);
}
/**
* Creates a CatchBlock representing a catch statement with the
* specified elements.
*/
public static CatchBlock makeCatchBlock(Type type,
ParameterExpression variable, Expression body, Expression filter) {
throw Extensions.todo();
}
/**
* Creates a DynamicExpression that represents a dynamic
* operation bound by the provided CallSiteBinder.
*/
public static DynamicExpression makeDynamic(Type type, CallSiteBinder binder,
Iterable<? extends Expression> arguments) {
throw Extensions.todo();
}
/**
* Creates a DynamicExpression that represents a dynamic
* operation bound by the provided CallSiteBinder, using varargs.
*/
public static DynamicExpression makeDynamic(Type type, CallSiteBinder binder,
Expression... arguments) {
throw Extensions.todo();
}
/**
* Creates a GotoExpression representing a jump of the specified
* GotoExpressionKind. The value passed to the label upon jumping
* can also be specified.
*/
public static GotoStatement makeGoto(GotoExpressionKind kind,
LabelTarget target, Expression value, Type type) {
throw Extensions.todo();
}
/**
* Creates a MemberExpression that represents accessing a field.
*/
public static MemberExpression makeMemberAccess(Expression expression,
PseudoField member) {
return new MemberExpression(expression, member);
}
/**
* Creates a TryExpression representing a try block with the
* specified elements.
*/
public static TryStatement makeTry(Type type, Expression body,
Expression finally_, Expression fault,
Iterable<? extends CatchBlock> handlers) {
throw Extensions.todo();
}
/**
* Creates a TryExpression representing a try block with the
* specified elements, using varargs.
*/
public static TryStatement makeTry(Type type, Expression body,
Expression finally_, Expression fault,
CatchBlock... handlers) {
throw Extensions.todo();
}
/**
* Creates a UnaryExpression, given an operand, by calling the
* appropriate factory method.
*/
public static UnaryExpression makeUnary(ExpressionType expressionType,
Expression expression) {
return new UnaryExpression(expressionType, expression.getType(),
expression);
}
/**
* Creates a UnaryExpression, given an operand and implementing
* method, by calling the appropriate factory method.
*/
public static UnaryExpression makeUnary(ExpressionType expressionType,
Expression expression, Type type, Method method) {
assert type != null;
return new UnaryExpression(expressionType, type, expression);
}
/**
* Creates a MemberMemberBinding that represents the recursive
* initialization of members of a field or property.
*/
public static MemberMemberBinding memberBind(Member member,
Iterable<? extends MemberBinding> bindings) {
throw Extensions.todo();
}
/**
* Creates a MemberMemberBinding that represents the recursive
* initialization of members of a field or property, using varargs.
*/
public static MemberMemberBinding memberBind(Member member,
MemberBinding... bindings) {
return memberBind(member, toList(bindings));
}
/**
* Creates a MemberMemberBinding that represents the recursive
* initialization of members of a member that is accessed by using
* a property accessor method.
*/
public static MemberMemberBinding memberBind(Method method,
Iterable<? extends MemberBinding> bindings) {
throw Extensions.todo();
}
/**
* Creates a MemberMemberBinding that represents the recursive
* initialization of members of a member that is accessed by using
* a property accessor method, using varargs.
*/
public static MemberMemberBinding memberBind(Method method,
MemberBinding... bindings) {
return memberBind(method, toList(bindings));
}
/**
* Represents an expression that creates a new object and
* initializes a property of the object.
*/
public static MemberInitExpression memberInit(NewExpression newExpression,
Iterable<? extends MemberBinding> bindings) {
throw Extensions.todo();
}
/**
* Represents an expression that creates a new object and
* initializes a property of the object, using varargs.
*/
public static MemberInitExpression memberInit(NewExpression newExpression,
MemberBinding... bindings) {
return memberInit(newExpression, toList(bindings));
}
/**
* Declares a method.
*/
public static MethodDeclaration methodDecl(int modifier, Type resultType,
String name, Iterable<? extends ParameterExpression> parameters,
BlockStatement body) {
return new MethodDeclaration(modifier, name, resultType, toList(parameters),
body);
}
/**
* Declares a constructor.
*/
public static ConstructorDeclaration constructorDecl(int modifier,
Type declaredAgainst, Iterable<? extends ParameterExpression> parameters,
BlockStatement body) {
return new ConstructorDeclaration(modifier, declaredAgainst, toList(
parameters), body);
}
/**
* Declares a field.
*/
public static FieldDeclaration fieldDecl(int modifier,
ParameterExpression parameter, Expression initializer) {
return new FieldDeclaration(modifier, parameter, initializer);
}
/**
* Declares a class.
*/
public static ClassDeclaration classDecl(int modifier, String name,
Type extended, List<Type> implemented,
List<MemberDeclaration> memberDeclarations) {
return new ClassDeclaration(modifier, name, extended, implemented,
memberDeclarations);
}
/**
* Creates a BinaryExpression that represents an arithmetic
* remainder operation.
*/
public static BinaryExpression modulo(Expression left, Expression right) {
return makeBinary(ExpressionType.Modulo, left, right);
}
/**
* Creates a BinaryExpression that represents an arithmetic
* remainder operation.
*/
public static BinaryExpression modulo(Expression left, Expression right,
Method method) {
return makeBinary(ExpressionType.Modulo, left, right, shouldLift(left,
right, method), method);
}
/**
* Creates a BinaryExpression that represents a remainder
* assignment operation.
*/
public static BinaryExpression moduloAssign(Expression left,
Expression right) {
return makeBinary(ExpressionType.ModuloAssign, left, right);
}
/**
* Creates a BinaryExpression that represents a remainder
* assignment operation.
*/
public static BinaryExpression moduloAssign(Expression left, Expression right,
Method method) {
return makeBinary(ExpressionType.ModuloAssign, left, right, false, method);
}
/**
* Creates a BinaryExpression that represents a remainder
* assignment operation.
*/
public static BinaryExpression moduloAssign(Expression left, Expression right,
Method method, LambdaExpression lambdaExpression) {
return makeBinary(ExpressionType.ModuloAssign, left, right, false, method,
lambdaExpression);
}
/**
* Creates a BinaryExpression that represents an arithmetic
* multiplication operation that does not have overflow
* checking.
*/
public static BinaryExpression multiply(Expression left, Expression right) {
return makeBinary(ExpressionType.Multiply, left, right);
}
/**
* Creates a BinaryExpression that represents an arithmetic
* multiplication operation that does not have overflow
* checking.
*/
public static BinaryExpression multiply(Expression left, Expression right,
Method method) {
return makeBinary(ExpressionType.Multiply, left, right, shouldLift(left,
right, method), method);
}
/**
* Creates a BinaryExpression that represents a multiplication
* assignment operation that does not have overflow checking.
*/
public static BinaryExpression multiplyAssign(Expression left,
Expression right) {
return makeBinary(ExpressionType.MultiplyAssign, left, right);
}
/**
* Creates a BinaryExpression that represents a multiplication
* assignment operation that does not have overflow checking.
*/
public static BinaryExpression multiplyAssign(Expression left,
Expression right, Method method) {
return makeBinary(ExpressionType.MultiplyAssign, left, right, false,
method);
}
/**
* Creates a BinaryExpression that represents a multiplication
* assignment operation that does not have overflow checking.
*/
public static BinaryExpression multiplyAssign(Expression left,
Expression right, Method method, LambdaExpression lambdaExpression) {
return makeBinary(ExpressionType.MultiplyAssign, left, right, false, method,
lambdaExpression);
}
/**
* Creates a BinaryExpression that represents a multiplication
* assignment operation that has overflow checking.
*/
public static BinaryExpression multiplyAssignChecked(Expression left,
Expression right) {
return makeBinary(ExpressionType.MultiplyAssignChecked, left, right);
}
/**
* Creates a BinaryExpression that represents a multiplication
* assignment operation that has overflow checking.
*/
public static BinaryExpression multiplyAssignChecked(Expression left,
Expression right, Method method) {
return makeBinary(ExpressionType.MultiplyAssignChecked, left, right, false,
method);
}
/**
* Creates a BinaryExpression that represents a multiplication
* assignment operation that has overflow checking.
*/
public static BinaryExpression multiplyAssignChecked(Expression left,
Expression right, Method method, LambdaExpression lambdaExpression) {
return makeBinary(ExpressionType.MultiplyAssignChecked, left, right, false,
method, lambdaExpression);
}
/**
* Creates a BinaryExpression that represents an arithmetic
* multiplication operation that has overflow checking.
*/
public static BinaryExpression multiplyChecked(Expression left,
Expression right) {
return makeBinary(ExpressionType.MultiplyChecked, left, right);
}
/**
* Creates a BinaryExpression that represents an arithmetic
* multiplication operation that has overflow checking.
*/
public static BinaryExpression multiplyChecked(Expression left,
Expression right, Method method) {
return makeBinary(ExpressionType.MultiplyChecked, left, right, shouldLift(
left, right, method), method);
}
/**
* Creates a UnaryExpression that represents an arithmetic
* negation operation.
*/
public static UnaryExpression negate(Expression expression) {
return makeUnary(ExpressionType.Negate, expression);
}
/**
* Creates a UnaryExpression that represents an arithmetic
* negation operation.
*/
public static UnaryExpression negate(Expression expression, Method method) {
return makeUnary(ExpressionType.Negate, expression, null, method);
}
/**
* Creates a UnaryExpression that represents an arithmetic
* negation operation that has overflow checking.
*/
public static UnaryExpression negateChecked(Expression expression) {
return makeUnary(ExpressionType.NegateChecked, expression);
}
/**
* Creates a UnaryExpression that represents an arithmetic
* negation operation that has overflow checking. The implementing
* method can be specified.
*/
public static UnaryExpression negateChecked(Expression expression,
Method method) {
return makeUnary(ExpressionType.NegateChecked, expression, null, method);
}
/**
* Creates a NewExpression that represents calling the specified
* constructor that takes no arguments.
*/
public static NewExpression new_(Constructor constructor) {
return new_(
constructor.getDeclaringClass(), Collections.<Expression>emptyList());
}
/**
* Creates a NewExpression that represents calling the
* parameterless constructor of the specified type.
*/
public static NewExpression new_(Type type) {
return new_(type, Collections.<Expression>emptyList());
}
/**
* Creates a NewExpression that represents calling the constructor of the
* specified type whose parameters are assignable from the specified
* arguments.
*/
public static NewExpression new_(Type type,
Iterable<? extends Expression> arguments) {
// Note that the last argument is not an empty list. That would cause
// an anonymous inner-class with no members to be generated.
return new NewExpression(type, toList(arguments), null);
}
/**
* Creates a NewExpression that represents calling the constructor of the
* specified type whose parameters are assignable from the specified
* arguments, using varargs.
*/
public static NewExpression new_(Type type, Expression... arguments) {
// Note that the last argument is not an empty list. That would cause
// an anonymous inner-class with no members to be generated.
return new NewExpression(type, toList(arguments), null);
}
/**
* Creates a NewExpression that represents calling the constructor of the
* specified type whose parameters are assignable from the specified
* arguments.
*/
public static NewExpression new_(Type type,
Iterable<? extends Expression> arguments,
Iterable<? extends MemberDeclaration> memberDeclarations) {
return new NewExpression(type, toList(arguments),
toList(memberDeclarations));
}
/**
* Creates a NewExpression that represents calling the constructor of the
* specified type whose parameters are assignable from the specified
* arguments, using varargs.
*/
public static NewExpression new_(Type type,
Iterable<? extends Expression> arguments,
MemberDeclaration... memberDeclarations) {
return new NewExpression(type, toList(arguments),
toList(memberDeclarations));
}
/**
* Creates a NewExpression that represents calling the specified
* constructor with the specified arguments.
*/
public static NewExpression new_(Constructor constructor,
Iterable<? extends Expression> expressions) {
// Note that the last argument is not an empty list. That would cause
// an anonymous inner-class with no members to be generated.
return new NewExpression(constructor.getDeclaringClass(),
toList(expressions), null);
}
/**
* Creates a NewExpression that represents calling the specified
* constructor with the specified arguments, using varargs.
*/
public static NewExpression new_(Constructor constructor,
Expression... expressions) {
return new NewExpression(constructor.getDeclaringClass(),
toList(expressions), null);
}
/**
* Creates a NewExpression that represents calling the specified
* constructor with the specified arguments.
*
* <p>The members that access the constructor initialized fields are
* specified.
*/
public static NewExpression new_(Constructor constructor,
Iterable<? extends Expression> expressions,
Iterable<? extends MemberDeclaration> memberDeclarations) {
return new_(constructor.getDeclaringClass(), toList(expressions),
toList(memberDeclarations));
}
/**
* Creates a NewExpression that represents calling the specified
* constructor with the specified arguments, using varargs.
*
* <p>The members that access the constructor initialized fields are
* specified.
*/
public static NewExpression new_(Constructor constructor,
Iterable<? extends Expression> expressions,
MemberDeclaration... memberDeclarations) {
return new_(constructor.getDeclaringClass(), toList(expressions),
toList(memberDeclarations));
}
/**
* Creates a NewArrayExpression that represents creating an array
* that has a specified rank.
*/
public static NewArrayExpression newArrayBounds(Type type,
Iterable<? extends Expression> expressions) {
throw Extensions.todo();
}
/**
* Creates a NewArrayExpression that represents creating an array
* that has a specified rank, using varargs.
*/
public static NewArrayExpression newArrayBounds(Type type,
Expression... expressions) {
return newArrayBounds(type, toList(expressions));
}
/**
* Creates a NewArrayExpression that represents creating a
* one-dimensional array and initializing it from a list of
* elements.
*
* @param type Element type of the array.
*/
public static NewArrayExpression newArrayInit(Type type,
Iterable<? extends Expression> expressions) {
return new NewArrayExpression(type, toList(expressions));
}
/**
* Creates a NewArrayExpression that represents creating a
* one-dimensional array and initializing it from a list of
* elements, using varargs.
*
* @param type Element type of the array.
*/
public static NewArrayExpression newArrayInit(Type type,
Expression... expressions) {
return newArrayInit(type, toList(expressions));
}
/**
* Creates a UnaryExpression that represents a bitwise complement
* operation.
*/
public static UnaryExpression not(Expression expression) {
return makeUnary(ExpressionType.Not, expression);
}
/**
* Creates a UnaryExpression that represents a bitwise complement
* operation. The implementing method can be specified.
*/
public static UnaryExpression not(Expression expression, Method method) {
return makeUnary(ExpressionType.Not, expression, null, method);
}
/**
* Creates a BinaryExpression that represents an inequality
* comparison.
*/
public static BinaryExpression notEqual(Expression left, Expression right) {
return makeBinary(ExpressionType.NotEqual, left, right);
}
/**
* Creates a BinaryExpression that represents an inequality
* comparison.
*/
public static BinaryExpression notEqual(Expression left, Expression right,
boolean liftToNull, Method method) {
return makeBinary(ExpressionType.NotEqual, left, right, liftToNull, method);
}
/**
* Returns the expression representing the ones complement.
*/
public static UnaryExpression onesComplement(Expression expression) {
return makeUnary(ExpressionType.OnesComplement, expression);
}
/**
* Returns the expression representing the ones complement.
*/
public static UnaryExpression onesComplement(Expression expression,
Method method) {
return makeUnary(ExpressionType.OnesComplement, expression,
expression.getType(), method);
}
/**
* Creates a BinaryExpression that represents a bitwise OR
* operation.
*/
public static BinaryExpression or(Expression left, Expression right) {
return makeBinary(ExpressionType.Or, left, right);
}
/**
* Creates a BinaryExpression that represents a bitwise OR
* operation.
*/
public static BinaryExpression or(Expression left, Expression right,
Method method) {
return makeBinary(ExpressionType.Or, left, right, false, method);
}
/**
* Creates a BinaryExpression that represents a bitwise OR
* assignment operation.
*/
public static BinaryExpression orAssign(Expression left, Expression right) {
return makeBinary(ExpressionType.OrAssign, left, right);
}
/**
* Creates a BinaryExpression that represents a bitwise OR
* assignment operation.
*/
public static BinaryExpression orAssign(Expression left, Expression right,
Method method) {
return makeBinary(ExpressionType.OrAssign, left, right);
}
/**
* Creates a BinaryExpression that represents a bitwise OR
* assignment operation.
*/
public static BinaryExpression orAssign(Expression left, Expression right,
Method method, LambdaExpression lambdaExpression) {
return makeBinary(ExpressionType.OrAssign, left, right, false, method,
lambdaExpression);
}
/**
* Creates a BinaryExpression that represents a conditional OR
* operation that evaluates the second operand only if the first
* operand evaluates to false.
*/
public static BinaryExpression orElse(Expression left, Expression right) {
return makeBinary(ExpressionType.OrElse, left, right);
}
/**
* Creates a BinaryExpression that represents a conditional OR
* operation that evaluates the second operand only if the first
* operand evaluates to false.
*/
public static BinaryExpression orElse(Expression left, Expression right,
Method method) {
return makeBinary(ExpressionType.OrElse, left, right, false, method);
}
/**
* Creates a ParameterExpression node that can be used to
* identify a parameter or a variable in an expression tree.
*/
public static ParameterExpression parameter(Type type) {
return new ParameterExpression(type);
}
/**
* Creates a ParameterExpression node that can be used to
* identify a parameter or a variable in an expression tree.
*/
public static ParameterExpression parameter(Type type, String name) {
return new ParameterExpression(0, type, name);
}
/**
* Creates a ParameterExpression.
*/
public static ParameterExpression parameter(int modifiers, Type type,
String name) {
return new ParameterExpression(modifiers, type, name);
}
/**
* Creates a UnaryExpression that represents the assignment of
* the expression followed by a subsequent decrement by 1 of the
* original expression.
*/
public static UnaryExpression postDecrementAssign(Expression expression) {
return makeUnary(ExpressionType.PostDecrementAssign, expression);
}
/**
* Creates a UnaryExpression that represents the assignment of
* the expression followed by a subsequent decrement by 1 of the
* original expression.
*/
public static UnaryExpression postDecrementAssign(Expression expression,
Method method) {
return makeUnary(ExpressionType.PostDecrementAssign, expression,
expression.getType(), method);
}
/**
* Creates a UnaryExpression that represents the assignment of
* the expression followed by a subsequent increment by 1 of the
* original expression.
*/
public static UnaryExpression postIncrementAssign(Expression expression) {
return makeUnary(ExpressionType.PostIncrementAssign, expression);
}
/**
* Creates a UnaryExpression that represents the assignment of
* the expression followed by a subsequent increment by 1 of the
* original expression.
*/
public static UnaryExpression PostIncrementAssign(Expression expression,
Method method) {
return makeUnary(ExpressionType.PostIncrementAssign, expression,
expression.getType(), method);
}
/**
* Creates a BinaryExpression that represents raising a number to
* a power.
*/
// REVIEW: In Java this is a call to a lib function, Math.pow.
public static BinaryExpression power(Expression left, Expression right) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents raising a number to
* a power.
*/
// REVIEW: In Java this is a call to a lib function, Math.pow.
public static BinaryExpression power(Expression left, Expression right,
Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents raising an
* expression to a power and assigning the result back to the
* expression.
*/
// REVIEW: In Java this is a call to a lib function, Math.pow.
public static BinaryExpression powerAssign(Expression left,
Expression right) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents raising an
* expression to a power and assigning the result back to the
* expression.
*/
// REVIEW: In Java this is a call to a lib function, Math.pow.
public static BinaryExpression powerAssign(Expression left, Expression right,
Method method) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents raising an
* expression to a power and assigning the result back to the
* expression.
*/
public static BinaryExpression powerAssign(Expression left, Expression right,
Method method, LambdaExpression lambdaExpression) {
throw Extensions.todo();
}
/**
* Creates a UnaryExpression that decrements the expression by 1
* and assigns the result back to the expression.
*/
public static UnaryExpression preDecrementAssign(Expression expression) {
return makeUnary(ExpressionType.PreDecrementAssign, expression);
}
/**
* Creates a UnaryExpression that decrements the expression by 1
* and assigns the result back to the expression.
*/
public static UnaryExpression preDecrementAssign(Expression expression,
Method method) {
return makeUnary(ExpressionType.PreDecrementAssign, expression,
expression.getType(), method);
}
/**
* Creates a UnaryExpression that increments the expression by 1
* and assigns the result back to the expression.
*/
public static UnaryExpression preIncrementAssign(Expression expression) {
return makeUnary(ExpressionType.PreIncrementAssign, expression);
}
/**
* Creates a UnaryExpression that increments the expression by 1
* and assigns the result back to the expression.
*/
public static UnaryExpression preIncrementAssign(Expression expression,
Method method) {
return makeUnary(ExpressionType.PreIncrementAssign, expression,
expression.getType(), method);
}
/**
* Creates a MemberExpression that represents accessing a
* property by using a property accessor method.
*/
// REVIEW: No equivalent to properties in Java.
public static MemberExpression property(Expression expression,
Method method) {
throw Extensions.todo();
}
/**
* Creates a MemberExpression that represents accessing a
* property.
*/
// REVIEW: No equivalent to properties in Java.
public static MemberExpression property(Expression expression,
PropertyInfo property) {
throw Extensions.todo();
}
/**
* Creates a MemberExpression that represents accessing a
* property.
*/
// REVIEW: No equivalent to properties in Java.
public static MemberExpression property(Expression expression, String name) {
throw Extensions.todo();
}
/**
* Creates an IndexExpression representing the access to an
* indexed property.
*/
// REVIEW: No equivalent to properties in Java.
public static IndexExpression property(Expression expression,
PropertyInfo property, Iterable<? extends Expression> arguments) {
throw Extensions.todo();
}
/**
* Creates an IndexExpression representing the access to an
* indexed property, using varargs.
*/
// REVIEW: No equivalent to properties in Java.
public static IndexExpression property(Expression expression,
PropertyInfo property, Expression... arguments) {
throw Extensions.todo();
}
/**
* Creates an IndexExpression representing the access to an
* indexed property.
*/
// REVIEW: No equivalent to properties in Java.
public static IndexExpression property(Expression expression, String name,
Expression... arguments) {
throw Extensions.todo();
}
/**
* Creates a MemberExpression accessing a property.
*/
public static MemberExpression property(Expression expression, Type type,
String name) {
throw Extensions.todo();
}
/**
* Creates a MemberExpression that represents accessing a
* property or field.
*/
// REVIEW: Java does not have properties; can only be a field name.
public static MemberExpression propertyOrField(Expression expression,
String propertyOfFieldName) {
throw Extensions.todo();
}
/**
* Creates a UnaryExpression that represents an expression that
* has a constant value of type Expression.
*/
public static UnaryExpression quote(Expression expression) {
return makeUnary(ExpressionType.Quote, expression);
}
/**
* Reduces this node to a simpler expression. If CanReduce
* returns true, this should return a valid expression. This
* method can return another node which itself must be reduced.
*/
public static Expression reduce(Expression expression) {
throw Extensions.todo();
}
/**
* Reduces this node to a simpler expression. If CanReduce
* returns true, this should return a valid expression. This
* method can return another node which itself must be reduced.
*/
public static Expression reduceAndCheck(Expression expression) {
throw Extensions.todo();
}
/**
* Reduces the expression to a known node type (that is not an
* Extension node) or just returns the expression if it is already
* a known type.
*/
public static Expression reduceExtensions(Expression expression) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a reference
* equality comparison.
*/
public static Expression referenceEqual(Expression left, Expression right) {
return makeBinary(ExpressionType.Equal, left, right);
}
/**
* Creates a BinaryExpression that represents a reference
* inequality comparison.
*/
public static Expression referenceNotEqual(Expression left,
Expression right) {
return makeBinary(ExpressionType.NotEqual, left, right);
}
/**
* Creates a UnaryExpression that represents a rethrowing of an
* exception.
*/
public static UnaryExpression rethrow() {
throw Extensions.todo();
}
/**
* Creates a UnaryExpression that represents a rethrowing of an
* exception with a given type.
*/
public static UnaryExpression rethrow(Type type) {
throw Extensions.todo();
}
/**
* Creates a GotoExpression representing a return statement.
*/
public static GotoStatement return_(LabelTarget labelTarget) {
return return_(labelTarget, (Expression) null);
}
/**
* Creates a GotoExpression representing a return statement. The
* value passed to the label upon jumping can be specified.
*/
public static GotoStatement return_(LabelTarget labelTarget,
Expression expression) {
return makeGoto(GotoExpressionKind.Return, labelTarget, expression);
}
public static GotoStatement makeGoto(GotoExpressionKind kind,
LabelTarget labelTarget, Expression expression) {
return new GotoStatement(kind, labelTarget, expression);
}
/**
* Creates a GotoExpression representing a return statement with
* the specified type.
*/
public static GotoStatement return_(LabelTarget labelTarget, Type type) {
throw Extensions.todo();
}
/**
* Creates a GotoExpression representing a return statement with
* the specified type. The value passed to the label upon jumping
* can be specified.
*/
public static GotoStatement return_(LabelTarget labelTarget,
Expression expression, Type type) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents a bitwise
* right-shift operation.
*/
public static BinaryExpression rightShift(Expression left, Expression right) {
return makeBinary(ExpressionType.RightShift, left, right);
}
/**
* Creates a BinaryExpression that represents a bitwise
* right-shift operation.
*/
public static BinaryExpression rightShift(Expression left, Expression right,
Method method) {
return makeBinary(ExpressionType.RightShift, left, right, false, method);
}
/**
* Creates a BinaryExpression that represents a bitwise
* right-shift assignment operation.
*/
public static BinaryExpression rightShiftAssign(Expression left,
Expression right) {
return makeBinary(ExpressionType.RightShiftAssign, left, right);
}
/**
* Creates a BinaryExpression that represents a bitwise
* right-shift assignment operation.
*/
public static BinaryExpression rightShiftAssign(Expression left,
Expression right, Method method) {
return makeBinary(ExpressionType.RightShiftAssign, left, right, false,
method);
}
/**
* Creates a BinaryExpression that represents a bitwise
* right-shift assignment operation.
*/
public static BinaryExpression rightShiftAssign(Expression left,
Expression right, Method method, LambdaExpression lambdaExpression) {
return makeBinary(ExpressionType.RightShiftAssign, left, right, false,
method, lambdaExpression);
}
/**
* Creates an instance of RuntimeVariablesExpression.
*/
public static RuntimeVariablesExpression runtimeVariables(
Iterable<? extends ParameterExpression> expressions) {
throw Extensions.todo();
}
/**
* Creates an instance of RuntimeVariablesExpression, using varargs.
*/
public static RuntimeVariablesExpression runtimeVariables(
ParameterExpression... arguments) {
throw Extensions.todo();
}
/**
* Creates a BinaryExpression that represents an arithmetic
* subtraction operation that does not have overflow checking.
*/
public static BinaryExpression subtract(Expression left, Expression right) {
return makeBinary(ExpressionType.Subtract, left, right);
}
/**
* Creates a BinaryExpression that represents an arithmetic
* subtraction operation that does not have overflow checking.
*/
public static BinaryExpression subtract(Expression left, Expression right,
Method method) {
return makeBinary(ExpressionType.Subtract, left, right, shouldLift(left,
right, method), method);
}
/**
* Creates a BinaryExpression that represents a subtraction
* assignment operation that does not have overflow checking.
*/
public static BinaryExpression subtractAssign(Expression left,
Expression right) {
return makeBinary(ExpressionType.SubtractAssign, left, right);
}
/**
* Creates a BinaryExpression that represents a subtraction
* assignment operation that does not have overflow checking.
*/
public static BinaryExpression subtractAssign(Expression left,
Expression right, Method method) {
return makeBinary(ExpressionType.SubtractAssign, left, right, false,
method);
}
/**
* Creates a BinaryExpression that represents a subtraction
* assignment operation that does not have overflow checking.
*/
public static BinaryExpression subtractAssign(Expression left,
Expression right, Method method, LambdaExpression lambdaExpression) {
return makeBinary(ExpressionType.SubtractAssign, left, right, false, method,
lambdaExpression);
}
/**
* Creates a BinaryExpression that represents a subtraction
* assignment operation that has overflow checking.
*/
public static BinaryExpression subtractAssignChecked(Expression left,
Expression right) {
return makeBinary(ExpressionType.SubtractAssignChecked, left, right);
}
/**
* Creates a BinaryExpression that represents a subtraction
* assignment operation that has overflow checking.
*/
public static BinaryExpression subtractAssignChecked(Expression left,
Expression right, Method method) {
return makeBinary(ExpressionType.SubtractAssignChecked, left, right, false,
method);
}
/**
* Creates a BinaryExpression that represents a subtraction
* assignment operation that has overflow checking.
*/
public static BinaryExpression subtractAssignChecked(Expression left,
Expression right, Method method, LambdaExpression lambdaExpression) {
return makeBinary(ExpressionType.SubtractAssignChecked, left, right, false,
method, lambdaExpression);
}
/**
* Creates a BinaryExpression that represents an arithmetic
* subtraction operation that has overflow checking.
*/
public static BinaryExpression subtractChecked(Expression left,
Expression right) {
return makeBinary(ExpressionType.SubtractChecked, left, right);
}
/**
* Creates a BinaryExpression that represents an arithmetic
* subtraction operation that has overflow checking.
*/
public static BinaryExpression subtractChecked(Expression left,
Expression right, Method method) {
return makeBinary(ExpressionType.SubtractChecked, left, right, shouldLift(
left, right, method), method);
}
/**
* Creates a SwitchExpression that represents a switch statement
* without a default case.
*/
public static SwitchStatement switch_(Expression switchValue,
SwitchCase... cases) {
return switch_(switchValue, null, null, toList(cases));
}
/**
* Creates a SwitchExpression that represents a switch statement
* that has a default case.
*/
public static SwitchStatement switch_(Expression switchValue,
Expression defaultBody, SwitchCase... cases) {
return switch_(switchValue, defaultBody, null, toList(cases));
}
/**
* Creates a SwitchExpression that represents a switch statement
* that has a default case.
*/
public static SwitchStatement switch_(Expression switchValue,
Expression defaultBody, Method method,
Iterable<? extends SwitchCase> cases) {
throw Extensions.todo();
}
/**
* Creates a SwitchExpression that represents a switch statement
* that has a default case, using varargs.
*/
public static SwitchStatement switch_(Expression switchValue,
Expression defaultBody, Method method, SwitchCase... cases) {
return switch_(switchValue, defaultBody, method, toList(cases));
}
/**
* Creates a SwitchExpression that represents a switch statement
* that has a default case.
*/
public static SwitchStatement switch_(Type type, Expression switchValue,
Expression defaultBody, Method method,
Iterable<? extends SwitchCase> cases) {
throw Extensions.todo();
}
/**
* Creates a SwitchExpression that represents a switch statement
* that has a default case, using varargs.
*/
public static SwitchStatement switch_(Type type, Expression switchValue,
Expression defaultBody, Method method, SwitchCase... cases) {
return switch_(type, switchValue, defaultBody, method, toList(cases));
}
/**
* Creates a SwitchCase for use in a SwitchExpression.
*/
public static SwitchCase switchCase(Expression expression,
Iterable<? extends Expression> body) {
throw Extensions.todo();
}
/**
* Creates a SwitchCase for use in a SwitchExpression, with varargs.
*/
public static SwitchCase switchCase(Expression expression,
Expression... body) {
return switchCase(expression, toList(body));
}
/**
* Creates an instance of SymbolDocumentInfo.
*/
public static SymbolDocumentInfo symbolDocument(String fileName) {
throw Extensions.todo();
}
/**
* Creates an instance of SymbolDocumentInfo.
*/
public static SymbolDocumentInfo symbolDocument(String fileName,
UUID language) {
throw Extensions.todo();
}
/**
* Creates an instance of SymbolDocumentInfo.
*/
public static SymbolDocumentInfo symbolDocument(String fileName,
UUID language, UUID vendor) {
throw Extensions.todo();
}
/**
* Creates an instance of SymbolDocumentInfo.
*/
public static SymbolDocumentInfo symbolDocument(String filename,
UUID language, UUID vendor, UUID documentType) {
throw Extensions.todo();
}
/**
* Creates a UnaryExpression that represents a throwing of an
* exception.
*/
public static UnaryExpression throw_(Expression expression) {
throw Extensions.todo();
}
/**
* Creates a UnaryExpression that represents a throwing of an
* exception with a given type.
*/
public static UnaryExpression throw_(Expression expression, Type type) {
throw Extensions.todo();
}
/**
* Creates a TryExpression representing a try block with any
* number of catch statements and neither a fault nor finally
* block.
*/
public static TryStatement tryCatch(Expression body,
CatchBlock... handlers) {
throw Extensions.todo();
}
/**
* Creates a TryExpression representing a try block with any
* number of catch statements and a finally block.
*/
public static TryStatement tryCatchFinally(Expression body,
CatchBlock... handlers) {
throw Extensions.todo();
}
/**
* Creates a TryExpression representing a try block with a fault
* block and no catch statements.
*/
public static TryStatement tryFault(Expression body, Expression fault) {
throw Extensions.todo();
}
/**
* Creates a TryExpression representing a try block with a
* finally block and no catch statements.
*/
public static TryStatement tryFinally(Expression body, Expression fault) {
throw Extensions.todo();
}
/**
* Creates a Type object that represents a generic System.Action
* delegate type that has specific type arguments.
*/
public static boolean tryGetActionType(Class[] typeArgs,
Class[] outActionType) {
throw Extensions.todo();
}
/**
* Creates a Type object that represents a generic System.Func
* delegate type that has specific type arguments. The last type
* argument specifies the return type of the created delegate.
*/
public static boolean tryGetFuncType(Class[] typeArgs, Class[] outFuncType) {
throw Extensions.todo();
}
/**
* Creates a UnaryExpression that represents an explicit
* reference or boxing conversion where null is supplied if the
* conversion fails.
*/
public static UnaryExpression typeAs(Expression expression, Type type) {
throw Extensions.todo();
}
/**
* Creates a TypeBinaryExpression that compares run-time type
* identity.
*/
public static TypeBinaryExpression typeEqual(Expression expression,
Type type) {
throw Extensions.todo();
}
/**
* Creates a TypeBinaryExpression.
*/
public static TypeBinaryExpression typeIs(Expression expression, Type type) {
return new TypeBinaryExpression(ExpressionType.TypeIs, expression, type);
}
/**
* Creates a UnaryExpression that represents a unary plus
* operation.
*/
public static UnaryExpression unaryPlus(Expression expression) {
return makeUnary(ExpressionType.UnaryPlus, expression);
}
/**
* Creates a UnaryExpression that represents a unary plus
* operation.
*/
public static UnaryExpression unaryPlus(Expression expression,
Method method) {
return makeUnary(ExpressionType.UnaryPlus, expression, expression.getType(),
method);
}
/**
* Creates a UnaryExpression that represents an explicit
* unboxing.
*/
public static UnaryExpression unbox(Expression expression, Type type) {
return new UnaryExpression(ExpressionType.Unbox, type, expression);
}
/**
* Creates a ParameterExpression node that can be used to
* identify a parameter or a variable in an expression tree.
*/
public static ParameterExpression variable(Type type) {
throw Extensions.todo();
}
/**
* Creates a ParameterExpression node that can be used to
* identify a parameter or a variable in an expression tree.
*/
public static ParameterExpression variable(Type type, String name) {
return new ParameterExpression(0, type, name);
}
/**
* Reduces the node and then calls the visitor delegate on the
* reduced expression. The method throws an exception if the node
* is not reducible.
*/
public static Expression visitChildren(ExpressionVisitor visitor) {
throw Extensions.todo();
}
/**
* Creates a WhileExpression representing a while loop.
*/
public static WhileStatement while_(Expression condition, Statement body) {
return new WhileStatement(condition, body);
}
/**
* Creates a statement that declares a variable.
*/
public static DeclarationStatement declare(int modifiers,
ParameterExpression parameter, Expression initializer) {
return new DeclarationStatement(modifiers, parameter, initializer);
}
/**
* Creates an expression that declares and initializes a variable. No
* type is required; it is assumed that the variable is the same type as
* the initializer. You can retrieve the {@link ParameterExpression} from
* the {@link DeclarationStatement#parameter} field of the result.
*/
public static DeclarationStatement declare(int modifiers, String name,
Expression initializer) {
return declare(modifiers, parameter(initializer.getType(), name),
initializer);
}
/**
* Creates a statement that executes an expression.
*/
public static Statement statement(Expression expression) {
return new GotoStatement(GotoExpressionKind.Sequence, null, expression);
}
/** Combines a list of expressions using AND. Returns TRUE if the list is
* empty. */
public static Expression foldAnd(List<Expression> conditions) {
Expression e = null;
for (Expression condition : conditions) {
if (condition instanceof ConstantExpression) {
if ((Boolean) ((ConstantExpression) condition).value) {
continue;
} else {
return constant(false);
}
}
if (e == null) {
e = condition;
} else {
e = andAlso(e, condition);
}
}
if (e == null) {
return constant(true);
}
return e;
}
/** Combines a list of expressions using OR. Returns FALSE if the list is
* empty. */
public static Expression foldOr(List<Expression> conditions) {
Expression e = null;
for (Expression condition : conditions) {
if (condition instanceof ConstantExpression) {
if ((Boolean) ((ConstantExpression) condition).value) {
return constant(true);
} else {
continue;
}
}
if (e == null) {
e = condition;
} else {
e = orElse(e, condition);
}
}
if (e == null) {
return constant(false);
}
return e;
}
/**
* Creates an empty fluent list.
*/
public static <T> FluentList<T> list() {
return new FluentArrayList<T>();
}
/**
* Creates a fluent list with given elements.
*/
public static <T> FluentList<T> list(T... ts) {
return new FluentArrayList<T>(Arrays.asList(ts));
}
/**
* Creates a fluent list with elements from the given collection.
*/
public static <T> FluentList<T> list(Iterable<T> ts) {
return new FluentArrayList<T>(toList(ts));
}
// ~ Private helper methods ------------------------------------------------
private static boolean shouldLift(Expression left, Expression right,
Method method) {
// FIXME: Implement the rules in modulo
return true;
}
private static Class deduceType(List<ParameterExpression> parameterList,
Type type) {
switch (parameterList.size()) {
case 0:
return Function0.class;
case 1:
return type == Boolean.TYPE ? Predicate1.class : Function1.class;
case 2:
return type == Boolean.TYPE ? Predicate2.class : Function2.class;
default:
return Function.class;
}
}
private static <T> List<T> toList(Iterable<? extends T> iterable) {
if (iterable == null) {
return null;
}
if (iterable instanceof List) {
return (List<T>) iterable;
}
final List<T> list = new ArrayList<T>();
for (T parameter : iterable) {
list.add(parameter);
}
return list;
}
private static <T> List<T> toList(T[] ts) {
if (ts.length == 0) {
return Collections.emptyList();
} else {
return Arrays.asList(ts);
}
}
private static <T> Collection<T> toCollection(Iterable<T> iterable) {
if (iterable instanceof Collection) {
return (Collection<T>) iterable;
}
return toList(iterable);
}
private static <T> T[] toArray(Iterable<T> iterable, T[] a) {
return toCollection(iterable).toArray(a);
}
static <T extends Expression> Expression accept(T node, Visitor visitor) {
if (node == null) {
return null;
}
return node.accept(visitor);
}
static <T extends Statement> Statement accept(T node, Visitor visitor) {
if (node == null) {
return null;
}
return node.accept(visitor);
}
static List<Statement> acceptStatements(List<Statement> statements,
Visitor visitor) {
if (statements.isEmpty()) {
return statements; // short cut
}
final List<Statement> statements1 = new ArrayList<Statement>();
for (Statement statement : statements) {
statements1.add(statement.accept(visitor));
}
return statements1;
}
static List<Node> acceptNodes(List<Node> nodes, Visitor visitor) {
if (nodes.isEmpty()) {
return nodes; // short cut
}
final List<Node> statements1 = new ArrayList<Node>();
for (Node node : nodes) {
statements1.add(node.accept(visitor));
}
return statements1;
}
static List<Expression> acceptParameterExpressions(
List<ParameterExpression> parameterExpressions, Visitor visitor) {
if (parameterExpressions.isEmpty()) {
return Collections.emptyList(); // short cut
}
final List<Expression> parameterExpressions1 = new ArrayList<Expression>();
for (ParameterExpression parameterExpression : parameterExpressions) {
parameterExpressions1.add(parameterExpression.accept(visitor));
}
return parameterExpressions1;
}
static List<DeclarationStatement> acceptDeclarations(
List<DeclarationStatement> declarations, Visitor visitor) {
if (declarations == null || declarations.isEmpty()) {
return declarations; // short cut
}
final List<DeclarationStatement> declarations1 =
new ArrayList<DeclarationStatement>();
for (DeclarationStatement declaration : declarations) {
declarations1.add(declaration.accept(visitor));
}
return declarations1;
}
static List<MemberDeclaration> acceptMemberDeclarations(
List<MemberDeclaration> memberDeclarations, Visitor visitor) {
if (memberDeclarations == null || memberDeclarations.isEmpty()) {
return memberDeclarations; // short cut
}
final List<MemberDeclaration> memberDeclarations1 =
new ArrayList<MemberDeclaration>();
for (MemberDeclaration memberDeclaration : memberDeclarations) {
memberDeclarations1.add(memberDeclaration.accept(visitor));
}
return memberDeclarations1;
}
static List<Expression> acceptExpressions(List<Expression> expressions,
Visitor visitor) {
if (expressions.isEmpty()) {
return expressions; // short cut
}
final List<Expression> expressions1 = new ArrayList<Expression>();
for (Expression expression : expressions) {
expressions1.add(expression.accept(visitor));
}
return expressions1;
}
// ~ Classes and interfaces ------------------------------------------------
// Some interfaces we'd rather not implement yet. They don't seem relevant
// in the Java world.
interface PropertyInfo {
}
interface RuntimeVariablesExpression {
}
interface SymbolDocumentInfo {
}
public interface FluentList<T> extends List<T> {
FluentList<T> append(T t);
FluentList<T> appendIf(boolean condition, T t);
FluentList<T> appendIfNotNull(T t);
FluentList<T> appendAll(Iterable<T> ts);
FluentList<T> appendAll(T... ts);
}
private static class FluentArrayList<T> extends ArrayList<T>
implements FluentList<T> {
public FluentArrayList() {
super();
}
public FluentArrayList(Collection<? extends T> c) {
super(c);
}
public FluentList<T> append(T t) {
add(t);
return this;
}
public FluentList<T> appendIf(boolean condition, T t) {
if (condition) {
add(t);
}
return this;
}
public FluentList<T> appendIfNotNull(T t) {
if (t != null) {
add(t);
}
return this;
}
public FluentList<T> appendAll(Iterable<T> ts) {
addAll(toCollection(ts));
return this;
}
public FluentList<T> appendAll(T... ts) {
addAll(Arrays.asList(ts));
return this;
}
}
}
// End Expressions.java