Release 0.1.8.
Rename BlockExpression to BlockStatement (because it is a Statement, not an Expression); similarly DeclarationStatement, GotoStatement, LabelStatement, SwitchStatement, TryStatement.
Rename LoopExpression to ForStatement, and implement for old-style "for(;;)".
Add a few convenience methods to BlockBuilder.
diff --git a/pom.xml b/pom.xml
index fa63c75..3197205 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,8 +8,8 @@
<packaging>jar</packaging>
<!-- Version number. The version number committed to github should be
- TRUNK-SNAPSHOT except, briefly, when making a release. Next up: 0.1.8. -->
- <version>TRUNK-SNAPSHOT</version>
+ TRUNK-SNAPSHOT except, briefly, when making a release. Next: 0.1.9. -->
+ <version>0.1.8</version>
<!-- More project information. -->
<name>linq4j</name>
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/BlockBuilder.java b/src/main/java/net/hydromatic/linq4j/expressions/BlockBuilder.java
index 919dbf8..9491620 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/BlockBuilder.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/BlockBuilder.java
@@ -21,7 +21,7 @@
import java.util.*;
/**
- * Builder for {@link BlockExpression}.
+ * Builder for {@link BlockStatement}.
*
* <p>Has methods that help ensure that variable names are unique.</p>
*/
@@ -59,7 +59,7 @@
* (possibly a variable) that represents the result of the newly added
* block.
*/
- public Expression append(String name, BlockExpression block) {
+ public Expression append(String name, BlockStatement block) {
return append(name, block, true);
}
@@ -73,14 +73,14 @@
* a variable. Do not do this if the expression has
* side-effects or a time-dependent value.
*/
- public Expression append(String name, BlockExpression block,
+ public Expression append(String name, BlockStatement block,
boolean optimize) {
if (statements.size() > 0) {
Statement lastStatement = statements.get(statements.size() - 1);
- if (lastStatement instanceof GotoExpression) {
+ if (lastStatement instanceof GotoStatement) {
// convert "return expr;" into "expr;"
statements.set(statements.size() - 1, Expressions.statement(
- ((GotoExpression) lastStatement).expression));
+ ((GotoStatement) lastStatement).expression));
}
}
Expression result = null;
@@ -93,8 +93,8 @@
// Save effort, and only substitute variables if there are some.
statement = statement.accept(visitor);
}
- if (statement instanceof DeclarationExpression) {
- DeclarationExpression declaration = (DeclarationExpression) statement;
+ if (statement instanceof DeclarationStatement) {
+ DeclarationStatement declaration = (DeclarationStatement) statement;
if (variables.contains(declaration.parameter.name)) {
Expression x = append(
newName(declaration.parameter.name, optimize),
@@ -109,18 +109,18 @@
add(statement);
}
if (i == block.statements.size() - 1) {
- if (statement instanceof DeclarationExpression) {
- result = ((DeclarationExpression) statement).parameter;
- } else if (statement instanceof GotoExpression) {
+ if (statement instanceof DeclarationStatement) {
+ result = ((DeclarationStatement) statement).parameter;
+ } else if (statement instanceof GotoStatement) {
statements.remove(statements.size() - 1);
- result = append_(name, ((GotoExpression) statement).expression,
+ result = append_(name, ((GotoStatement) statement).expression,
optimize);
if (result instanceof ParameterExpression
|| result instanceof ConstantExpression) {
// already simple; no need to declare a variable or
// even to evaluate the expression
} else {
- DeclarationExpression declare = Expressions.declare(Modifier.FINAL,
+ DeclarationStatement declare = Expressions.declare(Modifier.FINAL,
newName(name, optimize), result);
add(declare);
result = declare.parameter;
@@ -143,6 +143,16 @@
}
/**
+ * Appends an expression to a list of statements, if it is not null.
+ */
+ public Expression appendIfNotNull(String name, Expression expression) {
+ if (expression == null) {
+ return null;
+ }
+ return append(name, expression, true);
+ }
+
+ /**
* Appends an expression to a list of statements, optionally optimizing if
* the expression is used more than once.
*/
@@ -150,10 +160,10 @@
boolean optimize) {
if (statements.size() > 0) {
Statement lastStatement = statements.get(statements.size() - 1);
- if (lastStatement instanceof GotoExpression) {
+ if (lastStatement instanceof GotoStatement) {
// convert "return expr;" into "expr;"
statements.set(statements.size() - 1, Expressions.statement(
- ((GotoExpression) lastStatement).expression));
+ ((GotoStatement) lastStatement).expression));
}
}
return append_(name, expression, optimize);
@@ -172,8 +182,8 @@
}
if (optimizing) {
for (Statement statement : statements) {
- if (statement instanceof DeclarationExpression) {
- DeclarationExpression decl = (DeclarationExpression) statement;
+ if (statement instanceof DeclarationStatement) {
+ DeclarationStatement decl = (DeclarationStatement) statement;
if ((decl.modifiers & Modifier.FINAL) != 0
&& decl.initializer != null
&& decl.initializer.equals(expression)) {
@@ -182,7 +192,7 @@
}
}
}
- DeclarationExpression declare = Expressions.declare(Modifier.FINAL, newName(
+ DeclarationStatement declare = Expressions.declare(Modifier.FINAL, newName(
name, optimize), expression);
add(declare);
return declare.parameter;
@@ -190,8 +200,8 @@
public void add(Statement statement) {
statements.add(statement);
- if (statement instanceof DeclarationExpression) {
- String name = ((DeclarationExpression) statement).parameter.name;
+ if (statement instanceof DeclarationStatement) {
+ String name = ((DeclarationStatement) statement).parameter.name;
if (!variables.add(name)) {
throw new AssertionError("duplicate variable " + name);
}
@@ -205,7 +215,7 @@
/**
* Returns a block consisting of the current list of statements.
*/
- public BlockExpression toBlock() {
+ public BlockStatement toBlock() {
if (optimizing) {
optimize();
}
@@ -220,8 +230,8 @@
List<Slot> slots = new ArrayList<Slot>();
final UseCounter useCounter = new UseCounter();
for (Statement statement : statements) {
- if (statement instanceof DeclarationExpression) {
- final Slot slot = new Slot((DeclarationExpression) statement);
+ if (statement instanceof DeclarationStatement) {
+ final Slot slot = new Slot((DeclarationStatement) statement);
useCounter.map.put(slot.parameter, slot);
slots.add(slot);
}
@@ -237,8 +247,8 @@
statements);
statements.clear();
for (Statement oldStatement : oldStatements) {
- if (oldStatement instanceof DeclarationExpression) {
- DeclarationExpression statement = (DeclarationExpression) oldStatement;
+ if (oldStatement instanceof DeclarationStatement) {
+ DeclarationStatement statement = (DeclarationStatement) oldStatement;
final Slot slot = useCounter.map.get(statement.parameter);
int count = slot.count;
if (Expressions.isConstantNull(slot.expression)) {
@@ -288,13 +298,21 @@
}
/**
- * Creates a name for a new variable, unique within this block.
+ * Creates a name for a new variable, unique within this block, controlling
+ * whether the variable can be inlined later.
*/
private String newName(String suggestion, boolean optimize) {
if (!optimize && !suggestion.startsWith("_")) {
// "_" prefix reminds us not to consider the variable for inlining
suggestion = '_' + suggestion;
}
+ return newName(suggestion);
+ }
+
+ /**
+ * Creates a name for a new variable, unique within this block.
+ */
+ public String newName(String suggestion) {
int i = 0;
String candidate = suggestion;
for (;;) {
@@ -364,9 +382,9 @@
private final Expression expression;
private int count;
- public Slot(DeclarationExpression declarationExpression) {
- this.parameter = declarationExpression.parameter;
- this.expression = declarationExpression.initializer;
+ public Slot(DeclarationStatement declarationStatement) {
+ this.parameter = declarationStatement.parameter;
+ this.expression = declarationStatement.initializer;
}
}
}
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/BlockExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/BlockStatement.java
similarity index 86%
rename from src/main/java/net/hydromatic/linq4j/expressions/BlockExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/BlockStatement.java
index 23c295f..b18802e 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/BlockExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/BlockStatement.java
@@ -26,10 +26,10 @@
* Represents a block that contains a sequence of expressions where variables
* can be defined.
*/
-public class BlockExpression extends Statement {
+public class BlockStatement extends Statement {
public final List<Statement> statements;
- BlockExpression(List<Statement> statements, Type type) {
+ BlockStatement(List<Statement> statements, Type type) {
super(ExpressionType.Block, type);
this.statements = statements;
assert distinctVariables(true);
@@ -38,8 +38,8 @@
private boolean distinctVariables(boolean fail) {
Set<String> names = new HashSet<String>();
for (Statement statement : statements) {
- if (statement instanceof DeclarationExpression) {
- String name = ((DeclarationExpression) statement).parameter.name;
+ if (statement instanceof DeclarationStatement) {
+ String name = ((DeclarationStatement) statement).parameter.name;
if (!names.add(name)) {
assert !fail : "duplicate variable " + name;
return false;
@@ -50,7 +50,7 @@
}
@Override
- public BlockExpression accept(Visitor visitor) {
+ public BlockStatement accept(Visitor visitor) {
List<Statement> newStatements = Expressions.acceptStatements(statements,
visitor);
return visitor.visit(this, newStatements);
@@ -79,4 +79,4 @@
}
}
-// End BlockExpression.java
+// End BlockStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/Blocks.java b/src/main/java/net/hydromatic/linq4j/expressions/Blocks.java
index 12792c2..6f56803 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/Blocks.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/Blocks.java
@@ -18,9 +18,8 @@
package net.hydromatic.linq4j.expressions;
/**
- * <p>Helper methods concerning {@link BlockExpression}s.</p>
+ * <p>Helper methods concerning {@link BlockStatement}s.</p>
*
- * @author jhyde
* @see BlockBuilder
*/
public final class Blocks {
@@ -28,9 +27,9 @@
throw new AssertionError("no blocks for you!");
}
- private static BlockExpression toFunctionBlock(Node body, boolean function) {
- if (body instanceof BlockExpression) {
- return (BlockExpression) body;
+ private static BlockStatement toFunctionBlock(Node body, boolean function) {
+ if (body instanceof BlockStatement) {
+ return (BlockStatement) body;
}
Statement statement;
if (body instanceof Statement) {
@@ -50,19 +49,19 @@
return Expressions.block(statement);
}
- public static BlockExpression toFunctionBlock(Node body) {
+ public static BlockStatement toFunctionBlock(Node body) {
return toFunctionBlock(body, true);
}
- public static BlockExpression toBlock(Node body) {
+ public static BlockStatement toBlock(Node body) {
return toFunctionBlock(body, false);
}
/**
* Prepends a statement to a block.
*/
- public static BlockExpression create(Statement statement,
- BlockExpression block) {
+ public static BlockStatement create(Statement statement,
+ BlockStatement block) {
return Expressions.block(Expressions.list(statement).appendAll(
block.statements));
}
@@ -71,11 +70,11 @@
* Converts a simple "{ return expr; }" block into "expr"; otherwise
* throws.
*/
- public static Expression simple(BlockExpression block) {
+ public static Expression simple(BlockStatement block) {
if (block.statements.size() == 1) {
Statement statement = block.statements.get(0);
- if (statement instanceof GotoExpression) {
- return ((GotoExpression) statement).expression;
+ if (statement instanceof GotoStatement) {
+ return ((GotoStatement) statement).expression;
}
}
throw new AssertionError("not a simple block: " + block);
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/ConstructorDeclaration.java b/src/main/java/net/hydromatic/linq4j/expressions/ConstructorDeclaration.java
index 0d4d385..17231c6 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/ConstructorDeclaration.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/ConstructorDeclaration.java
@@ -29,10 +29,10 @@
public final int modifier;
public final Type resultType;
public final List<ParameterExpression> parameters;
- public final BlockExpression body;
+ public final BlockStatement body;
public ConstructorDeclaration(int modifier, Type declaredAgainst,
- List<ParameterExpression> parameters, BlockExpression body) {
+ List<ParameterExpression> parameters, BlockStatement body) {
this.modifier = modifier;
this.resultType = declaredAgainst;
this.parameters = parameters;
@@ -42,7 +42,7 @@
@Override
public MemberDeclaration accept(Visitor visitor) {
// do not visit parameters
- final BlockExpression body = this.body.accept(visitor);
+ final BlockStatement body = this.body.accept(visitor);
return visitor.visit(this, parameters, body);
}
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/DeclarationExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/DeclarationStatement.java
similarity index 73%
rename from src/main/java/net/hydromatic/linq4j/expressions/DeclarationExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/DeclarationStatement.java
index 3f27441..1b91086 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/DeclarationExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/DeclarationStatement.java
@@ -21,15 +21,13 @@
/**
* Expression that declares and optionally initializes a variable.
- *
- * @author jhyde
*/
-public class DeclarationExpression extends Statement {
+public class DeclarationStatement extends Statement {
public final int modifiers;
public final ParameterExpression parameter;
public final Expression initializer;
- public DeclarationExpression(int modifiers, ParameterExpression parameter,
+ public DeclarationStatement(int modifiers, ParameterExpression parameter,
Expression initializer) {
super(ExpressionType.Declaration, Void.TYPE);
this.modifiers = modifiers;
@@ -38,7 +36,7 @@
}
@Override
- public Statement accept(Visitor visitor) {
+ public DeclarationStatement accept(Visitor visitor) {
// do not visit parameter - visit may not return a ParameterExpression
Expression initializer = this.initializer != null
? this.initializer.accept(visitor)
@@ -59,6 +57,22 @@
writer.append(';');
writer.newlineAndIndent();
}
+
+ public void accept2(ExpressionWriter writer, boolean withType) {
+ if (withType) {
+ final String modifiers = Modifier.toString(this.modifiers);
+ if (!modifiers.isEmpty()) {
+ writer.append(modifiers).append(' ');
+ }
+ writer.append(parameter.type).append(' ');
+ } else {
+ writer.append(", ");
+ }
+ writer.append(parameter.name);
+ if (initializer != null) {
+ writer.append(" = ").append(initializer);
+ }
+ }
}
-// End DeclarationExpression.java
+// End DeclarationStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/ExpressionType.java b/src/main/java/net/hydromatic/linq4j/expressions/ExpressionType.java
index a4707d8..81e25eb 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/ExpressionType.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/ExpressionType.java
@@ -582,6 +582,8 @@
*/
Declaration,
+ For,
+
While;
final String op;
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/Expressions.java b/src/main/java/net/hydromatic/linq4j/expressions/Expressions.java
index 8c61461..ca2bcdc 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/Expressions.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/Expressions.java
@@ -209,8 +209,8 @@
*/
public static IndexExpression arrayIndex(Expression array,
Expression indexExpression) {
- return new IndexExpression(array, Collections.singletonList(
- indexExpression));
+ return new IndexExpression(array,
+ Collections.singletonList(indexExpression));
}
/**
@@ -248,23 +248,24 @@
/**
* Creates a BlockExpression that contains the given statements.
*/
- public static BlockExpression block(Statement... statements) {
- return block(toList(statements));
+ public static BlockStatement block(
+ Iterable<? extends Statement> statements) {
+ return block((Type) null, statements);
}
/**
- * Creates a BlockExpression that contains the given statements.
+ * Creates a BlockExpression that contains the given statements,
+ * using varargs.
*/
- public static BlockExpression block(
- Iterable<? extends Statement> statements) {
- return block((Type) null, statements);
+ 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 BlockExpression block(Type type,
+ public static BlockStatement block(Type type,
Iterable<? extends Statement> expressions) {
List<Statement> list = toList(expressions);
if (type == null) {
@@ -274,38 +275,38 @@
type = Void.TYPE;
}
}
- return new BlockExpression(list, type);
+ return new BlockStatement(list, type);
}
/**
* Creates a BlockExpression that contains the given statements
- * and has a specific result type.
+ * and has a specific result type, using varargs.
*/
- public static BlockExpression block(Type type, Statement... statements) {
+ public static BlockStatement block(Type type, Statement... statements) {
return block(type, toList(statements));
}
/**
* Creates a GotoExpression representing a break statement.
*/
- public static GotoExpression break_(LabelTarget labelTarget) {
- throw Extensions.todo();
+ 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 GotoExpression break_(LabelTarget labelTarget,
+ public static GotoStatement break_(LabelTarget labelTarget,
Expression expression) {
- throw Extensions.todo();
+ return new GotoStatement(GotoExpressionKind.Break, null, expression);
}
/**
* Creates a GotoExpression representing a break statement with
* the specified type.
*/
- public static GotoExpression break_(LabelTarget labelTarget, Type type) {
+ public static GotoStatement break_(LabelTarget labelTarget, Type type) {
throw Extensions.todo();
}
@@ -314,23 +315,23 @@
* the specified type. The value passed to the label upon jumping
* can be specified.
*/
- public static GotoExpression break_(LabelTarget labelTarget,
+ public static GotoStatement break_(LabelTarget labelTarget,
Expression expression, Type type) {
throw Extensions.todo();
}
/**
* Creates a MethodCallExpression that represents a call to a
- * static method.
+ * static method that has arguments.
*/
public static MethodCallExpression call(Method method,
- Iterable<Expression> expressions) {
- return new MethodCallExpression(method, null, toList(expressions));
+ 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.
+ * static method that has arguments, using varargs.
*/
public static MethodCallExpression call(Method method,
Expression... arguments) {
@@ -342,7 +343,16 @@
* method that takes arguments.
*/
public static MethodCallExpression call(Expression expression, Method method,
- Iterable<Expression> arguments) {
+ 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));
}
@@ -357,37 +367,27 @@
* is static.</p>
*/
public static MethodCallExpression call(Type returnType,
- Expression expression, Method method, Iterable<Expression> arguments) {
- return new MethodCallExpression(returnType, method, expression, toList(
- arguments));
+ 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.
+ * 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(Expression expression, Method method,
+ public static MethodCallExpression call(Type returnType,
+ Expression expression, Method method,
Expression... arguments) {
- return new MethodCallExpression(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 expression,
- String methodName, Iterable<Expression> arguments) {
- Method method;
- try {
- method = Types.toClass(expression.getType()).getMethod(methodName,
- Types.toClassArray(arguments));
- } catch (NoSuchMethodException e) {
- throw new RuntimeException("while resolving method '"
- + methodName
- + "' in class "
- + expression.getType(), e);
- }
- return call(expression, method, arguments);
+ return new MethodCallExpression(returnType, method, expression,
+ toList(arguments));
}
/**
@@ -395,8 +395,26 @@
* 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, Arrays.<Expression>asList(arguments));
+ return call(target, methodName, toList(arguments));
}
/**
@@ -405,7 +423,7 @@
* appropriate factory method.
*/
public static MethodCallExpression call(Type type, String methodName,
- Iterable<Expression> arguments) {
+ Iterable<? extends Expression> arguments) {
Method method = Types.lookupMethod(Types.toClass(type), methodName,
Types.toClassArray(arguments));
return new MethodCallExpression(method, null, toList(arguments));
@@ -414,11 +432,11 @@
/**
* Creates a MethodCallExpression that represents a call to a
* static method by calling the
- * appropriate factory method.
+ * appropriate factory method, using varargs.
*/
public static MethodCallExpression call(Type type, String methodName,
Expression... arguments) {
- return call(type, methodName, Arrays.<Expression>asList(arguments));
+ return call(type, methodName, toList(arguments));
}
/**
@@ -556,7 +574,7 @@
if (value != null && type instanceof Class) {
// Fix up value so that it matches type.
Class clazz = (Class) type;
- Primitive primitive = Primitive.of(clazz);
+ Primitive primitive = Primitive.ofBoxOr(clazz);
if (primitive != null) {
clazz = primitive.boxClass;
}
@@ -579,7 +597,7 @@
/**
* Creates a GotoExpression representing a continue statement.
*/
- public static GotoExpression continue_(LabelTarget labelTarget) {
+ public static GotoStatement continue_(LabelTarget labelTarget) {
throw Extensions.todo();
}
@@ -587,7 +605,7 @@
* Creates a GotoExpression representing a continue statement
* with the specified type.
*/
- public static GotoExpression continue_(LabelTarget labelTarget, Type type) {
+ public static GotoStatement continue_(LabelTarget labelTarget, Type type) {
throw Extensions.todo();
}
@@ -712,22 +730,13 @@
* operation bound by the provided CallSiteBinder.
*/
public static DynamicExpression dynamic(CallSiteBinder binder, Type type,
- Iterable<Expression> expressions) {
+ Iterable<? extends Expression> expressions) {
throw Extensions.todo();
}
/**
* Creates a DynamicExpression that represents a dynamic
- * operation bound by the provided CallSiteBinder.
- */
- public static DynamicExpression dynamic(CallSiteBinder binder, Type type,
- Expression expression) {
- throw Extensions.todo();
- }
-
- /**
- * Creates a DynamicExpression that represents a dynamic
- * operation bound by the provided CallSiteBinder.
+ * operation bound by the provided CallSiteBinder, using varargs.
*/
public static DynamicExpression dynamic(CallSiteBinder binder, Type type,
Expression... expression) {
@@ -739,13 +748,13 @@
* argument.
*/
public static ElementInit elementInit(Method method,
- Iterable<Expression> expressions) {
+ Iterable<? extends Expression> expressions) {
throw Extensions.todo();
}
/**
* Creates an ElementInit, given an array of values as the second
- * argument.
+ * argument, using varargs.
*/
public static ElementInit elementInit(Method method,
Expression... expressions) {
@@ -888,7 +897,7 @@
/**
* Creates a GotoExpression representing a "go to" statement.
*/
- public static GotoExpression goto_(LabelTarget labelTarget) {
+ public static GotoStatement goto_(LabelTarget labelTarget) {
throw Extensions.todo();
}
@@ -896,7 +905,7 @@
* Creates a GotoExpression representing a "go to" statement. The
* value passed to the label upon jumping can be specified.
*/
- public static GotoExpression goto_(LabelTarget labelTarget,
+ public static GotoStatement goto_(LabelTarget labelTarget,
Expression expression) {
throw Extensions.todo();
}
@@ -905,7 +914,7 @@
* Creates a GotoExpression representing a "go to" statement with
* the specified type.
*/
- public static GotoExpression goto_(LabelTarget labelTarget, Type type) {
+ public static GotoStatement goto_(LabelTarget labelTarget, Type type) {
throw Extensions.todo();
}
@@ -914,7 +923,7 @@
* the specified type. The value passed to the label upon jumping
* can be specified.
*/
- public static GotoExpression goto_(LabelTarget labelTarget,
+ public static GotoStatement goto_(LabelTarget labelTarget,
Expression expression, Type type) {
throw Extensions.todo();
}
@@ -995,13 +1004,13 @@
* lambda expression to a list of argument expressions.
*/
public static InvocationExpression invoke(Expression expression,
- Iterable<Expression> arguments) {
+ Iterable<? extends Expression> arguments) {
throw Extensions.todo();
}
/**
* Creates an InvocationExpression that applies a delegate or
- * lambda expression to a list of argument expressions.
+ * lambda expression to a list of argument expressions, using varargs.
*/
public static InvocationExpression invoke(Expression expression,
Expression... arguments) {
@@ -1048,7 +1057,7 @@
* Creates a LabelExpression representing a label without a
* default value.
*/
- public static LabelExpression label(LabelTarget labelTarget) {
+ public static LabelStatement label(LabelTarget labelTarget) {
throw Extensions.todo();
}
@@ -1072,7 +1081,7 @@
* Creates a LabelExpression representing a label with the given
* default value.
*/
- public static LabelExpression label(LabelTarget labelTarget,
+ public static LabelStatement label(LabelTarget labelTarget,
Expression expression) {
throw Extensions.todo();
}
@@ -1102,90 +1111,86 @@
* type.
*/
public static <F extends Function<?>> FunctionExpression<F> lambda(
- BlockExpression body, Iterable<ParameterExpression> parameters) {
+ 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.
+ * type, using varargs.
*/
public static <F extends Function<?>> FunctionExpression<F> lambda(
- Expression body, Iterable<ParameterExpression> parameters) {
- return lambda(Blocks.toFunctionBlock(body), parameters);
- }
-
- /**
- * Creates an Expression<TDelegate> where the delegate type is
- * known at compile time.
- */
- public static <TDelegate extends Function<?>> FunctionExpression<TDelegate>
- lambda(BlockExpression body, ParameterExpression... parameters) {
+ BlockStatement body, ParameterExpression... parameters) {
return lambda(body, toList(parameters));
}
/**
- * Creates an Expression<TDelegate> where the delegate type is
+ * Creates an Expression where the delegate type {@code F} is
* known at compile time.
*/
- public static <TDelegate extends Function<?>> FunctionExpression<TDelegate>
- lambda(Expression body, ParameterExpression... parameters) {
+ 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. It can be used when the delegate type is not known at
- * compile time.
+ * 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, BlockExpression body,
- Iterable<ParameterExpression> parameters) {
+ 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. It can be used when the delegate type is not known at
- * compile time.
+ * 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,
- Iterable<ParameterExpression> parameters) {
- return lambda(type, Blocks.toFunctionBlock(body), toList(parameters));
- }
-
- /**
- * Creates a LambdaExpression by first constructing a delegate
- * type. 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, BlockExpression body,
+ lambda(Class<F> type, BlockStatement body,
ParameterExpression... parameters) {
return lambda(type, body, toList(parameters));
}
/**
* Creates a LambdaExpression by first constructing a delegate
- * type. It can be used when the delegate type is not known at
- * compile time.
+ * 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, ParameterExpression... parameters) {
- return lambda(type, body, toList(parameters));
+ 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.
+ * 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(Type type, BlockExpression body, String name,
- Iterable<ParameterExpression> parameters) {
- throw Extensions.todo();
+ lambda(Class<F> type, Expression body, ParameterExpression... parameters) {
+ return lambda(type, Blocks.toFunctionBlock(body), toList(parameters));
}
/**
@@ -1272,13 +1277,13 @@
* property.
*/
public static MemberListBinding listBind(Member member,
- Iterable<ElementInit> elementInits) {
+ Iterable<? extends ElementInit> elementInits) {
throw Extensions.todo();
}
/**
* Creates a MemberListBinding where the member is a field or
- * property.
+ * property, using varargs.
*/
public static MemberListBinding listBind(Member member,
ElementInit... elementInits) {
@@ -1290,13 +1295,13 @@
* accessor method.
*/
public static MemberListBinding listBind(Method method,
- Iterable<ElementInit> elementInits) {
+ Iterable<? extends ElementInit> elementInits) {
throw Extensions.todo();
}
/**
* Creates a MemberListBinding object based on a specified
- * property accessor method.
+ * property accessor method, using varargs.
*/
public static MemberListBinding listBind(Method method,
ElementInit... elementInits) {
@@ -1308,22 +1313,13 @@
* objects to initialize a collection.
*/
public static ListInitExpression listInit(NewExpression newExpression,
- Iterable<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<Expression> arguments) {
+ Iterable<? extends ElementInit> elementInits) {
throw Extensions.todo();
}
/**
* Creates a ListInitExpression that uses specified ElementInit
- * objects to initialize a collection.
+ * objects to initialize a collection, using varargs.
*/
public static ListInitExpression listInit(NewExpression newExpression,
ElementInit... elementInits) {
@@ -1334,6 +1330,15 @@
* 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();
@@ -1344,13 +1349,13 @@
* add elements to a collection.
*/
public static ListInitExpression listInit(NewExpression newExpression,
- Method method, Iterable<Expression> arguments) {
+ Method method, Iterable<? extends Expression> arguments) {
throw Extensions.todo();
}
/**
* Creates a ListInitExpression that uses a specified method to
- * add elements to a collection.
+ * add elements to a collection, using varargs.
*/
public static ListInitExpression listInit(NewExpression newExpression,
Method method, Expression... arguments) {
@@ -1360,24 +1365,20 @@
/**
* Creates a LoopExpression with the given body.
*/
- public static LoopExpression loop(Expression body) {
- throw Extensions.todo();
- }
-
- /**
- * Creates a LoopExpression with the given body and break
- * target.
- */
- public static LoopExpression loop(Expression body, LabelTarget breakTarget) {
- throw Extensions.todo();
+ 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 LoopExpression loop(Expression body, LabelTarget breakTarget,
- LabelTarget continueTarget) {
- throw Extensions.todo();
+ public static ForStatement for_(
+ DeclarationStatement declaration,
+ Expression condition, Expression post, Statement body) {
+ return new ForStatement(Collections.singletonList(declaration), condition,
+ post, body);
}
/**
@@ -1525,23 +1526,13 @@
* operation bound by the provided CallSiteBinder.
*/
public static DynamicExpression makeDynamic(Type type, CallSiteBinder binder,
- Iterable<Expression> arguments) {
+ Iterable<? extends Expression> arguments) {
throw Extensions.todo();
}
/**
* Creates a DynamicExpression that represents a dynamic
- * operation bound by the provided CallSiteBinder and one
- * argument.
- */
- public static DynamicExpression makeDynamic(Type type, CallSiteBinder binder,
- Expression argument) {
- throw Extensions.todo();
- }
-
- /**
- * Creates a DynamicExpression that represents a dynamic
- * operation bound by the provided CallSiteBinder.
+ * operation bound by the provided CallSiteBinder, using varargs.
*/
public static DynamicExpression makeDynamic(Type type, CallSiteBinder binder,
Expression... arguments) {
@@ -1553,21 +1544,12 @@
* GotoExpressionKind. The value passed to the label upon jumping
* can also be specified.
*/
- public static GotoExpression makeGoto(GotoExpressionKind kind,
+ public static GotoStatement makeGoto(GotoExpressionKind kind,
LabelTarget target, Expression value, Type type) {
throw Extensions.todo();
}
/**
- * Creates an IndexExpression that represents accessing an
- * indexed property in an object.
- */
- public static IndexExpression makeIndex(Expression instance,
- PropertyInfo indexer, Iterable<Expression> arguments) {
- throw Extensions.todo();
- }
-
- /**
* Creates a MemberExpression that represents accessing a field.
*/
public static MemberExpression makeMemberAccess(Expression expression,
@@ -1579,8 +1561,19 @@
* Creates a TryExpression representing a try block with the
* specified elements.
*/
- public static TryExpression makeTry(Type type, Expression body,
- Expression finally_, Expression fault, Iterable<CatchBlock> handlers) {
+ 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();
}
@@ -1609,13 +1602,13 @@
* initialization of members of a field or property.
*/
public static MemberMemberBinding memberBind(Member member,
- Iterable<MemberBinding> bindings) {
+ Iterable<? extends MemberBinding> bindings) {
throw Extensions.todo();
}
/**
* Creates a MemberMemberBinding that represents the recursive
- * initialization of members of a field or property.
+ * initialization of members of a field or property, using varargs.
*/
public static MemberMemberBinding memberBind(Member member,
MemberBinding... bindings) {
@@ -1628,14 +1621,14 @@
* a property accessor method.
*/
public static MemberMemberBinding memberBind(Method method,
- Iterable<MemberBinding> bindings) {
+ 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.
+ * a property accessor method, using varargs.
*/
public static MemberMemberBinding memberBind(Method method,
MemberBinding... bindings) {
@@ -1647,12 +1640,13 @@
* initializes a property of the object.
*/
public static MemberInitExpression memberInit(NewExpression newExpression,
- Iterable<MemberBinding> bindings) {
+ Iterable<? extends MemberBinding> bindings) {
throw Extensions.todo();
}
/**
- * Creates a MemberInitExpression.
+ * 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) {
@@ -1663,8 +1657,8 @@
* Declares a method.
*/
public static MethodDeclaration methodDecl(int modifier, Type resultType,
- String name, Iterable<ParameterExpression> parameters,
- BlockExpression body) {
+ String name, Iterable<? extends ParameterExpression> parameters,
+ BlockStatement body) {
return new MethodDeclaration(modifier, name, resultType, toList(parameters),
body);
}
@@ -1673,8 +1667,8 @@
* Declares a constructor.
*/
public static ConstructorDeclaration constructorDecl(int modifier,
- Type declaredAgainst, Iterable<ParameterExpression> parameters,
- BlockExpression body) {
+ Type declaredAgainst, Iterable<? extends ParameterExpression> parameters,
+ BlockStatement body) {
return new ConstructorDeclaration(modifier, declaredAgainst, toList(
parameters), body);
}
@@ -1879,8 +1873,8 @@
* constructor that takes no arguments.
*/
public static NewExpression new_(Constructor constructor) {
- return new_(constructor.getDeclaringClass(),
- Collections.<Expression>emptyList());
+ return new_(
+ constructor.getDeclaringClass(), Collections.<Expression>emptyList());
}
/**
@@ -1896,10 +1890,22 @@
* specified type whose parameters are assignable from the specified
* arguments.
*/
- public static NewExpression new_(Type type, Iterable<Expression> 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_(type, arguments, null);
+ 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);
}
/**
@@ -1907,10 +1913,23 @@
* specified type whose parameters are assignable from the specified
* arguments.
*/
- public static NewExpression new_(Type type, Iterable<Expression> arguments,
- Iterable<MemberDeclaration> memberDeclarations) {
- return new NewExpression(type, toList(arguments), toList(
- memberDeclarations));
+ 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));
}
/**
@@ -1918,31 +1937,49 @@
* constructor with the specified arguments.
*/
public static NewExpression new_(Constructor constructor,
- Iterable<Expression> expressions) {
+ 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_(constructor.getDeclaringClass(), expressions, null);
+ return new NewExpression(constructor.getDeclaringClass(),
+ toList(expressions), null);
}
/**
* Creates a NewExpression that represents calling the specified
- * constructor with the specified arguments.
+ * constructor with the specified arguments, using varargs.
*/
public static NewExpression new_(Constructor constructor,
Expression... expressions) {
- return new_(constructor, toList(expressions));
+ return new NewExpression(constructor.getDeclaringClass(),
+ toList(expressions), null);
}
/**
* Creates a NewExpression that represents calling the specified
- * constructor with the specified arguments. The members that
- * access the constructor initialized fields are specified.
+ * constructor with the specified arguments.
+ *
+ * <p>The members that access the constructor initialized fields are
+ * specified.
*/
public static NewExpression new_(Constructor constructor,
- Iterable<Expression> expressions,
- Iterable<MemberDeclaration> memberDeclarations) {
- return new_(constructor.getDeclaringClass(), toList(expressions), toList(
- memberDeclarations));
+ 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));
}
/**
@@ -1950,13 +1987,13 @@
* that has a specified rank.
*/
public static NewArrayExpression newArrayBounds(Type type,
- Iterable<Expression> expressions) {
+ Iterable<? extends Expression> expressions) {
throw Extensions.todo();
}
/**
* Creates a NewArrayExpression that represents creating an array
- * that has a specified rank.
+ * that has a specified rank, using varargs.
*/
public static NewArrayExpression newArrayBounds(Type type,
Expression... expressions) {
@@ -1971,14 +2008,16 @@
* @param type Element type of the array.
*/
public static NewArrayExpression newArrayInit(Type type,
- Iterable<Expression> expressions) {
+ 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.
+ * elements, using varargs.
+ *
+ * @param type Element type of the array.
*/
public static NewArrayExpression newArrayInit(Type type,
Expression... expressions) {
@@ -2283,13 +2322,13 @@
*/
// REVIEW: No equivalent to properties in Java.
public static IndexExpression property(Expression expression,
- PropertyInfo property, Iterable<Expression> arguments) {
+ PropertyInfo property, Iterable<? extends Expression> arguments) {
throw Extensions.todo();
}
/**
* Creates an IndexExpression representing the access to an
- * indexed property.
+ * indexed property, using varargs.
*/
// REVIEW: No equivalent to properties in Java.
public static IndexExpression property(Expression expression,
@@ -2396,7 +2435,7 @@
/**
* Creates a GotoExpression representing a return statement.
*/
- public static GotoExpression return_(LabelTarget labelTarget) {
+ public static GotoStatement return_(LabelTarget labelTarget) {
return return_(labelTarget, (Expression) null);
}
@@ -2404,21 +2443,21 @@
* Creates a GotoExpression representing a return statement. The
* value passed to the label upon jumping can be specified.
*/
- public static GotoExpression return_(LabelTarget labelTarget,
+ public static GotoStatement return_(LabelTarget labelTarget,
Expression expression) {
return makeGoto(GotoExpressionKind.Return, labelTarget, expression);
}
- public static GotoExpression makeGoto(GotoExpressionKind kind,
+ public static GotoStatement makeGoto(GotoExpressionKind kind,
LabelTarget labelTarget, Expression expression) {
- return new GotoExpression(kind, labelTarget, expression);
+ return new GotoStatement(kind, labelTarget, expression);
}
/**
* Creates a GotoExpression representing a return statement with
* the specified type.
*/
- public static GotoExpression return_(LabelTarget labelTarget, Type type) {
+ public static GotoStatement return_(LabelTarget labelTarget, Type type) {
throw Extensions.todo();
}
@@ -2427,7 +2466,7 @@
* the specified type. The value passed to the label upon jumping
* can be specified.
*/
- public static GotoExpression return_(LabelTarget labelTarget,
+ public static GotoStatement return_(LabelTarget labelTarget,
Expression expression, Type type) {
throw Extensions.todo();
}
@@ -2482,12 +2521,12 @@
* Creates an instance of RuntimeVariablesExpression.
*/
public static RuntimeVariablesExpression runtimeVariables(
- Iterable<ParameterExpression> expressions) {
+ Iterable<? extends ParameterExpression> expressions) {
throw Extensions.todo();
}
/**
- * Creates an instance of RuntimeVariablesExpression.
+ * Creates an instance of RuntimeVariablesExpression, using varargs.
*/
public static RuntimeVariablesExpression runtimeVariables(
ParameterExpression... arguments) {
@@ -2593,7 +2632,7 @@
* Creates a SwitchExpression that represents a switch statement
* without a default case.
*/
- public static SwitchExpression switch_(Expression switchValue,
+ public static SwitchStatement switch_(Expression switchValue,
SwitchCase... cases) {
return switch_(switchValue, null, null, toList(cases));
}
@@ -2602,7 +2641,7 @@
* Creates a SwitchExpression that represents a switch statement
* that has a default case.
*/
- public static SwitchExpression switch_(Expression switchValue,
+ public static SwitchStatement switch_(Expression switchValue,
Expression defaultBody, SwitchCase... cases) {
return switch_(switchValue, defaultBody, null, toList(cases));
}
@@ -2611,16 +2650,17 @@
* Creates a SwitchExpression that represents a switch statement
* that has a default case.
*/
- public static SwitchExpression switch_(Expression switchValue,
- Expression defaultBody, Method method, Iterable<SwitchCase> cases) {
+ 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.
+ * that has a default case, using varargs.
*/
- public static SwitchExpression switch_(Expression switchValue,
+ public static SwitchStatement switch_(Expression switchValue,
Expression defaultBody, Method method, SwitchCase... cases) {
return switch_(switchValue, defaultBody, method, toList(cases));
}
@@ -2629,31 +2669,31 @@
* Creates a SwitchExpression that represents a switch statement
* that has a default case.
*/
- public static SwitchExpression switch_(Type type, Expression switchValue,
- Expression defaultBody, Method method, Iterable<SwitchCase> cases) {
+ 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..
+ * that has a default case, using varargs.
*/
- public static SwitchExpression switch_(Type type, Expression switchValue,
+ 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 object to be used in a SwitchExpression
- * object.
+ * Creates a SwitchCase for use in a SwitchExpression.
*/
public static SwitchCase switchCase(Expression expression,
- Iterable<Expression> body) {
+ Iterable<? extends Expression> body) {
throw Extensions.todo();
}
/**
- * Creates a SwitchCase for use in a SwitchExpression.
+ * Creates a SwitchCase for use in a SwitchExpression, with varargs.
*/
public static SwitchCase switchCase(Expression expression,
Expression... body) {
@@ -2712,7 +2752,7 @@
* number of catch statements and neither a fault nor finally
* block.
*/
- public static TryExpression tryCatch(Expression body,
+ public static TryStatement tryCatch(Expression body,
CatchBlock... handlers) {
throw Extensions.todo();
}
@@ -2721,7 +2761,7 @@
* Creates a TryExpression representing a try block with any
* number of catch statements and a finally block.
*/
- public static TryExpression tryCatchFinally(Expression body,
+ public static TryStatement tryCatchFinally(Expression body,
CatchBlock... handlers) {
throw Extensions.todo();
}
@@ -2730,7 +2770,7 @@
* Creates a TryExpression representing a try block with a fault
* block and no catch statements.
*/
- public static TryExpression tryFault(Expression body, Expression fault) {
+ public static TryStatement tryFault(Expression body, Expression fault) {
throw Extensions.todo();
}
@@ -2738,7 +2778,7 @@
* Creates a TryExpression representing a try block with a
* finally block and no catch statements.
*/
- public static TryExpression tryFinally(Expression body, Expression fault) {
+ public static TryStatement tryFinally(Expression body, Expression fault) {
throw Extensions.todo();
}
@@ -2839,25 +2879,25 @@
/**
* Creates a WhileExpression representing a while loop.
*/
- public static WhileExpression while_(Expression condition, Statement body) {
- return new WhileExpression(condition, body);
+ public static WhileStatement while_(Expression condition, Statement body) {
+ return new WhileStatement(condition, body);
}
/**
* Creates a statement that declares a variable.
*/
- public static DeclarationExpression declare(int modifiers,
+ public static DeclarationStatement declare(int modifiers,
ParameterExpression parameter, Expression initializer) {
- return new DeclarationExpression(modifiers, parameter, 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 DeclarationExpression#parameter} field of the result.
+ * the {@link DeclarationStatement#parameter} field of the result.
*/
- public static DeclarationExpression declare(int modifiers, String name,
+ public static DeclarationStatement declare(int modifiers, String name,
Expression initializer) {
return declare(modifiers, parameter(initializer.getType(), name),
initializer);
@@ -2867,7 +2907,7 @@
* Creates a statement that executes an expression.
*/
public static Statement statement(Expression expression) {
- return new GotoExpression(GotoExpressionKind.Sequence, null, expression);
+ return new GotoStatement(GotoExpressionKind.Sequence, null, expression);
}
/** Combines a list of expressions using AND. Returns TRUE if the list is
@@ -2933,7 +2973,7 @@
}
/**
- * Creates a fluent list with given elements.
+ * 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));
@@ -3043,6 +3083,19 @@
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()) {
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/ForStatement.java b/src/main/java/net/hydromatic/linq4j/expressions/ForStatement.java
new file mode 100644
index 0000000..0b9560b
--- /dev/null
+++ b/src/main/java/net/hydromatic/linq4j/expressions/ForStatement.java
@@ -0,0 +1,73 @@
+/*
+// 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.Ord;
+
+import java.util.List;
+
+/**
+ * Represents an infinite loop. It can be exited with "break".
+ */
+public class ForStatement extends Statement {
+ public final List<DeclarationStatement> declarations;
+ public final Expression condition;
+ public final Expression post;
+ public final Statement body;
+
+ public ForStatement(List<DeclarationStatement> declarations,
+ Expression condition, Expression post, Statement body) {
+ super(ExpressionType.For, Void.TYPE);
+ assert declarations != null;
+ assert body != null;
+ this.declarations = declarations; // may be empty, not null
+ this.condition = condition; // may be null
+ this.post = post; // may be null
+ this.body = body; // may be empty block, not null
+ }
+
+ @Override
+ public ForStatement accept(Visitor visitor) {
+ List<DeclarationStatement> decls1 =
+ Expressions.acceptDeclarations(declarations, visitor);
+ final Expression condition1 =
+ condition == null ? null : condition.accept(visitor);
+ final Expression post1 = post == null ? null : post.accept(visitor);
+ final Statement body1 = body.accept(visitor);
+ return visitor.visit(this, decls1, condition1, post1, body1);
+ }
+
+ @Override
+ void accept0(ExpressionWriter writer) {
+ writer.append("for (");
+ for (Ord<DeclarationStatement> declaration : Ord.zip(declarations)) {
+ declaration.e.accept2(writer, declaration.i == 0);
+ }
+ writer.append("; ");
+ if (condition != null) {
+ writer.append(condition);
+ }
+ writer.append("; ");
+ if (post != null) {
+ writer.append(post);
+ }
+ writer.append(") ").append(Blocks.toBlock(body));
+ }
+}
+
+// End ForStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/FunctionExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/FunctionExpression.java
index b7d7d61..bb1fe3f 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/FunctionExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/FunctionExpression.java
@@ -29,11 +29,11 @@
public final class FunctionExpression<F extends Function<?>>
extends LambdaExpression {
public final F function;
- public final BlockExpression body;
+ public final BlockStatement body;
public final List<ParameterExpression> parameterList;
private F dynamicFunction;
- private FunctionExpression(Class<F> type, F function, BlockExpression body,
+ private FunctionExpression(Class<F> type, F function, BlockStatement body,
List<ParameterExpression> parameterList) {
super(ExpressionType.Lambda, type);
assert type != null;
@@ -48,14 +48,14 @@
Collections.<ParameterExpression>emptyList());
}
- public FunctionExpression(Class<F> type, BlockExpression body,
+ public FunctionExpression(Class<F> type, BlockStatement body,
List<ParameterExpression> parameters) {
this(type, null, body, parameters);
}
@Override
public Expression accept(Visitor visitor) {
- BlockExpression body = this.body.accept(visitor);
+ BlockStatement body = this.body.accept(visitor);
return visitor.visit(this, body, parameterList);
}
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/GotoExpressionKind.java b/src/main/java/net/hydromatic/linq4j/expressions/GotoExpressionKind.java
index 61b25ad..bf84070 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/GotoExpressionKind.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/GotoExpressionKind.java
@@ -18,7 +18,7 @@
package net.hydromatic.linq4j.expressions;
/**
- * Specifies what kind of jump a {@link GotoExpression} represents.
+ * Specifies what kind of jump a {@link GotoStatement} represents.
*/
public enum GotoExpressionKind {
/**
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/GotoExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/GotoStatement.java
similarity index 90%
rename from src/main/java/net/hydromatic/linq4j/expressions/GotoExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/GotoStatement.java
index 494985a..932b253 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/GotoExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/GotoStatement.java
@@ -21,12 +21,12 @@
* Represents an unconditional jump. This includes return statements, break and
* continue statements, and other jumps.
*/
-public class GotoExpression extends Statement {
+public class GotoStatement extends Statement {
public final GotoExpressionKind kind;
public final LabelTarget labelTarget;
public final Expression expression;
- GotoExpression(GotoExpressionKind kind, LabelTarget labelTarget,
+ GotoStatement(GotoExpressionKind kind, LabelTarget labelTarget,
Expression expression) {
super(ExpressionType.Goto,
expression == null ? Void.TYPE : expression.getType());
@@ -54,8 +54,9 @@
@Override
public Statement accept(Visitor visitor) {
- Expression expression = this.expression.accept(visitor);
- return visitor.visit(this, expression);
+ Expression expression1 =
+ expression == null ? null : expression.accept(visitor);
+ return visitor.visit(this, expression1);
}
@Override
@@ -96,4 +97,4 @@
}
}
-// End GotoExpression.java
+// End GotoStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/LabelExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/LabelStatement.java
similarity index 81%
rename from src/main/java/net/hydromatic/linq4j/expressions/LabelExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/LabelStatement.java
index 1f35b5d..cf25219 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/LabelExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/LabelStatement.java
@@ -20,22 +20,22 @@
/**
* Represents a label, which can be put in any {@link Expression} context. If it
* is jumped to, it will get the value provided by the corresponding
- * {@link GotoExpression}. Otherwise, it receives the value in
+ * {@link GotoStatement}. Otherwise, it receives the value in
* {@link #defaultValue}. If the Type equals {@link Void}, no value should be
* provided.
*/
-public class LabelExpression extends Statement {
+public class LabelStatement extends Statement {
public final Expression defaultValue;
- public LabelExpression(Expression defaultValue, ExpressionType nodeType) {
+ public LabelStatement(Expression defaultValue, ExpressionType nodeType) {
super(nodeType, Void.TYPE);
this.defaultValue = defaultValue;
}
@Override
- public LabelExpression accept(Visitor visitor) {
+ public LabelStatement accept(Visitor visitor) {
return visitor.visit(this);
}
}
-// End LabelExpression.java
+// End LabelStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/LabelTarget.java b/src/main/java/net/hydromatic/linq4j/expressions/LabelTarget.java
index 974c413..2ad7381 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/LabelTarget.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/LabelTarget.java
@@ -18,7 +18,7 @@
package net.hydromatic.linq4j.expressions;
/**
- * Used to represent the target of a {@link GotoExpression}.
+ * Used to represent the target of a {@link GotoStatement}.
*/
public class LabelTarget {
public final String name;
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/LoopExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/LoopExpression.java
deleted file mode 100644
index aa84419..0000000
--- a/src/main/java/net/hydromatic/linq4j/expressions/LoopExpression.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-// 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;
-
-/**
- * Represents an infinite loop. It can be exited with "break".
- */
-public class LoopExpression extends Statement {
- public LoopExpression(ExpressionType nodeType) {
- super(nodeType, Void.TYPE);
- }
-
- @Override
- public LoopExpression accept(Visitor visitor) {
- return visitor.visit(this);
- }
-}
-
-// End LoopExpression.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/MethodDeclaration.java b/src/main/java/net/hydromatic/linq4j/expressions/MethodDeclaration.java
index d31eabc..306d46e 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/MethodDeclaration.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/MethodDeclaration.java
@@ -30,10 +30,10 @@
public final String name;
public final Type resultType;
public final List<ParameterExpression> parameters;
- public final BlockExpression body;
+ public final BlockStatement body;
public MethodDeclaration(int modifier, String name, Type resultType,
- List<ParameterExpression> parameters, BlockExpression body) {
+ List<ParameterExpression> parameters, BlockStatement body) {
this.modifier = modifier;
this.name = name;
this.resultType = resultType;
@@ -44,7 +44,7 @@
@Override
public MemberDeclaration accept(Visitor visitor) {
// do not visit parameters
- final BlockExpression body = this.body.accept(visitor);
+ final BlockStatement body = this.body.accept(visitor);
return visitor.visit(this, parameters, body);
}
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/SwitchCase.java b/src/main/java/net/hydromatic/linq4j/expressions/SwitchCase.java
index a724750..27dd250 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/SwitchCase.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/SwitchCase.java
@@ -18,7 +18,7 @@
package net.hydromatic.linq4j.expressions;
/**
- * Represents one case of a {@link SwitchExpression}.
+ * Represents one case of a {@link SwitchStatement}.
*/
public class SwitchCase {
}
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/SwitchExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/SwitchStatement.java
similarity index 88%
rename from src/main/java/net/hydromatic/linq4j/expressions/SwitchExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/SwitchStatement.java
index 54f9a4c..8ecfd2e 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/SwitchExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/SwitchStatement.java
@@ -21,8 +21,8 @@
* Represents a control expression that handles multiple selections by passing
* control to {@link SwitchCase}.
*/
-public class SwitchExpression extends Statement {
- public SwitchExpression(ExpressionType nodeType) {
+public class SwitchStatement extends Statement {
+ public SwitchStatement(ExpressionType nodeType) {
super(nodeType, Void.TYPE);
}
@@ -32,4 +32,4 @@
}
}
-// End SwitchExpression.java
+// End SwitchStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/TryExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/TryStatement.java
similarity index 88%
rename from src/main/java/net/hydromatic/linq4j/expressions/TryExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/TryStatement.java
index 0647431..35dac9f 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/TryExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/TryStatement.java
@@ -20,8 +20,8 @@
/**
* Represents a try/catch/finally/fault block.
*/
-public class TryExpression extends Statement {
- public TryExpression(ExpressionType nodeType) {
+public class TryStatement extends Statement {
+ public TryStatement(ExpressionType nodeType) {
super(nodeType, Void.TYPE);
}
@@ -31,4 +31,4 @@
}
}
-// End TryExpression.java
+// End TryStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/Types.java b/src/main/java/net/hydromatic/linq4j/expressions/Types.java
index ed01dbe..925878b 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/Types.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/Types.java
@@ -98,6 +98,8 @@
static PseudoField getField(String fieldName, Type type) {
if (type instanceof RecordType) {
return getRecordField(fieldName, (RecordType) type);
+ } else if (type instanceof Class && ((Class) type).isArray()) {
+ return getSystemField(fieldName, (Class) type);
} else {
return field(getField(fieldName, toClass(type)));
}
@@ -113,6 +115,36 @@
"Unknown field '" + fieldName + "' in type " + type);
}
+ private static RecordField getSystemField(final String fieldName,
+ final Class clazz) {
+ // The "length" field of an array does not appear in Class.getFields().
+ return new RecordField() {
+ public boolean nullable() {
+ return false;
+ }
+
+ public String getName() {
+ return fieldName;
+ }
+
+ public Type getType() {
+ return int.class;
+ }
+
+ public int getModifiers() {
+ return 0;
+ }
+
+ public Object get(Object o) throws IllegalAccessException {
+ return Array.getLength(o);
+ }
+
+ public Type getDeclaringClass() {
+ return clazz;
+ }
+ };
+ }
+
public static Class toClass(Type type) {
if (type instanceof Class) {
return (Class) type;
@@ -135,7 +167,7 @@
return classes.toArray(new Class[classes.size()]);
}
- static Class[] toClassArray(Iterable<Expression> arguments) {
+ static Class[] toClassArray(Iterable<? extends Expression> arguments) {
List<Class> classes = new ArrayList<Class>();
for (Expression argument : arguments) {
classes.add(toClass(argument.getType()));
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/Visitor.java b/src/main/java/net/hydromatic/linq4j/expressions/Visitor.java
index 7f73d56..8e05276 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/Visitor.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/Visitor.java
@@ -23,46 +23,48 @@
/**
* Node visitor.
- *
- * @author jhyde
*/
public class Visitor {
- public Statement visit(WhileExpression whileExpression, Expression condition,
+ public Statement visit(WhileStatement whileStatement, Expression condition,
Statement body) {
- return condition == whileExpression.condition
- && body == whileExpression.body
- ? whileExpression
+ return condition == whileStatement.condition
+ && body == whileStatement.body
+ ? whileStatement
: Expressions.while_(condition, body);
}
- public BlockExpression visit(BlockExpression blockExpression,
+ public BlockStatement visit(BlockStatement blockStatement,
List<Statement> statements) {
- return statements.equals(blockExpression.statements)
- ? blockExpression
+ return statements.equals(blockStatement.statements)
+ ? blockStatement
: Expressions.block(statements);
}
- public Statement visit(GotoExpression gotoExpression, Expression expression) {
- return expression == gotoExpression.expression
- ? gotoExpression
- : Expressions.makeGoto(gotoExpression.kind, gotoExpression.labelTarget,
+ public Statement visit(GotoStatement gotoStatement, Expression expression) {
+ return expression == gotoStatement.expression
+ ? gotoStatement
+ : Expressions.makeGoto(
+ gotoStatement.kind, gotoStatement.labelTarget,
expression);
}
- public LabelExpression visit(LabelExpression labelExpression) {
- return labelExpression;
+ public LabelStatement visit(LabelStatement labelStatement) {
+ return labelStatement;
}
- public LoopExpression visit(LoopExpression loopExpression) {
- return loopExpression;
+ public ForStatement visit(ForStatement forStatement,
+ List<DeclarationStatement> declarations, Expression condition,
+ Expression post, Statement body) {
+ return forStatement;
}
- public Statement visit(DeclarationExpression declarationExpression,
+ public DeclarationStatement visit(DeclarationStatement declarationStatement,
ParameterExpression parameter, Expression initializer) {
- return declarationExpression.parameter == parameter
- && declarationExpression.initializer == initializer
- ? declarationExpression
- : Expressions.declare(declarationExpression.modifiers, parameter,
+ return declarationStatement.parameter == parameter
+ && declarationStatement.initializer == initializer
+ ? declarationStatement
+ : Expressions.declare(
+ declarationStatement.modifiers, parameter,
initializer);
}
@@ -71,7 +73,7 @@
}
public Expression visit(FunctionExpression functionExpression,
- BlockExpression body, List<ParameterExpression> parameterList) {
+ BlockStatement body, List<ParameterExpression> parameterList) {
return functionExpression.body.equals(body)
&& functionExpression.parameterList.equals(parameterList)
? functionExpression
@@ -161,12 +163,12 @@
: Expressions.new_(newExpression.type, arguments, memberDeclarations);
}
- public Statement visit(SwitchExpression switchExpression) {
- return switchExpression;
+ public Statement visit(SwitchStatement switchStatement) {
+ return switchStatement;
}
- public Statement visit(TryExpression tryExpression) {
- return tryExpression;
+ public Statement visit(TryStatement tryStatement) {
+ return tryStatement;
}
public Expression visit(MemberInitExpression memberInitExpression) {
@@ -179,7 +181,7 @@
}
public MemberDeclaration visit(MethodDeclaration methodDeclaration,
- List<ParameterExpression> parameters, BlockExpression body) {
+ List<ParameterExpression> parameters, BlockStatement body) {
return parameters.equals(methodDeclaration.parameters)
&& body.equals(methodDeclaration.body)
? methodDeclaration
@@ -211,7 +213,7 @@
}
public MemberDeclaration visit(ConstructorDeclaration constructorDeclaration,
- List<ParameterExpression> parameters, BlockExpression body) {
+ List<ParameterExpression> parameters, BlockStatement body) {
return constructorDeclaration;
}
}
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/WhileExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/WhileStatement.java
similarity index 90%
rename from src/main/java/net/hydromatic/linq4j/expressions/WhileExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/WhileStatement.java
index 8ca2528..6b680f2 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/WhileExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/WhileStatement.java
@@ -20,11 +20,11 @@
/**
* Represents a "while" statement.
*/
-public class WhileExpression extends Statement {
+public class WhileStatement extends Statement {
public final Expression condition;
public final Statement body;
- public WhileExpression(Expression condition, Statement body) {
+ public WhileStatement(Expression condition, Statement body) {
super(ExpressionType.While, Void.TYPE);
this.condition = condition;
this.body = body;
@@ -44,4 +44,4 @@
}
}
-// End WhileExpression.java
+// End WhileStatement.java
diff --git a/src/test/java/net/hydromatic/linq4j/test/ExpressionTest.java b/src/test/java/net/hydromatic/linq4j/test/ExpressionTest.java
index 08747b4..30dbfe8 100644
--- a/src/test/java/net/hydromatic/linq4j/test/ExpressionTest.java
+++ b/src/test/java/net/hydromatic/linq4j/test/ExpressionTest.java
@@ -293,6 +293,13 @@
"empno")));
assertEquals(
+ "a.length",
+ Expressions.toString(
+ Expressions.field(
+ Expressions.parameter(Object[].class, "a"),
+ "length")));
+
+ assertEquals(
"java.util.Collections.EMPTY_LIST",
Expressions.toString(
Expressions.field(
@@ -541,7 +548,7 @@
Expressions.parameter(
Integer.TYPE,
"index");
- BlockExpression e =
+ BlockStatement e =
Expressions.block(
Expressions.declare(
Modifier.FINAL,
@@ -609,7 +616,7 @@
}
@Test public void testWriteWhile() {
- DeclarationExpression xDecl, yDecl;
+ DeclarationStatement xDecl, yDecl;
Node node =
Expressions.block(
xDecl = Expressions.declare(
@@ -948,6 +955,61 @@
Expressions.toString(builder.toBlock()));
}
+ @Test public void testFor() throws NoSuchFieldException {
+ final BlockBuilder builder = new BlockBuilder();
+ final ParameterExpression i_ = Expressions.parameter(int.class, "i");
+ builder.add(
+ Expressions.for_(
+ Expressions.declare(
+ 0, i_, Expressions.constant(0)),
+ Expressions.lessThan(i_, Expressions.constant(10)),
+ Expressions.postIncrementAssign(i_),
+ Expressions.block(
+ Expressions.statement(
+ Expressions.call(
+ Expressions.field(
+ null, System.class.getField("out")),
+ "println",
+ i_)))));
+ assertEquals(
+ "{\n"
+ + " for (int i = 0; i < 10; i++) {\n"
+ + " System.out.println(i);\n"
+ + " }\n"
+ + "}\n",
+ Expressions.toString(builder.toBlock()));
+ }
+
+ @Test public void testFor2() throws NoSuchFieldException {
+ final BlockBuilder builder = new BlockBuilder();
+ final ParameterExpression i_ = Expressions.parameter(int.class, "i");
+ final ParameterExpression j_ = Expressions.parameter(int.class, "j");
+ builder.add(
+ Expressions.for_(
+ Arrays.asList(
+ Expressions.declare(
+ 0, i_, Expressions.constant(0)),
+ Expressions.declare(
+ 0, j_, Expressions.constant(10))),
+ null,
+ null,
+ Expressions.block(
+ Expressions.ifThen(
+ Expressions.lessThan(
+ Expressions.preIncrementAssign(i_),
+ Expressions.preDecrementAssign(j_)),
+ Expressions.break_(null)))));
+ assertEquals(
+ "{\n"
+ + " for (int i = 0, j = 10; ; ) {\n"
+ + " if (++i < --j) {\n"
+ + " break;\n"
+ + " }\n"
+ + " }\n"
+ + "}\n",
+ Expressions.toString(builder.toBlock()));
+ }
+
enum MyEnum {
X,
Y {