using System.Collections.Generic;
using IronJava.Core.AST.Visitors;
namespace IronJava.Core.AST.Nodes
{
///
/// Base class for all expressions.
///
public abstract class Expression : JavaNode
{
protected Expression(SourceRange location) : base(location) { }
}
///
/// Represents a literal value.
///
public class LiteralExpression : Expression
{
public object? Value { get; }
public LiteralKind Kind { get; }
public LiteralExpression(SourceRange location, object? value, LiteralKind kind)
: base(location)
{
Value = value;
Kind = kind;
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitLiteralExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitLiteralExpression(this);
}
public enum LiteralKind
{
Null,
Boolean,
Integer,
Long,
Float,
Double,
Character,
String,
TextBlock
}
///
/// Represents an identifier reference.
///
public class IdentifierExpression : Expression
{
public string Name { get; }
public IdentifierExpression(SourceRange location, string name) : base(location)
{
Name = name;
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitIdentifierExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitIdentifierExpression(this);
}
///
/// Represents 'this' expression.
///
public class ThisExpression : Expression
{
public Expression? Qualifier { get; }
public ThisExpression(SourceRange location, Expression? qualifier = null) : base(location)
{
Qualifier = qualifier;
if (qualifier != null) AddChild(qualifier);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitThisExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitThisExpression(this);
}
///
/// Represents 'super' expression.
///
public class SuperExpression : Expression
{
public Expression? Qualifier { get; }
public SuperExpression(SourceRange location, Expression? qualifier = null) : base(location)
{
Qualifier = qualifier;
if (qualifier != null) AddChild(qualifier);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitSuperExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitSuperExpression(this);
}
///
/// Represents a binary expression (a + b, a AND b, etc.).
///
public class BinaryExpression : Expression
{
public Expression Left { get; }
public BinaryOperator Operator { get; }
public Expression Right { get; }
public BinaryExpression(
SourceRange location,
Expression left,
BinaryOperator @operator,
Expression right) : base(location)
{
Left = left;
Operator = @operator;
Right = right;
AddChild(left);
AddChild(right);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitBinaryExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitBinaryExpression(this);
}
public enum BinaryOperator
{
// Arithmetic
Add, Subtract, Multiply, Divide, Modulo,
// Bitwise
BitwiseAnd, BitwiseOr, BitwiseXor, LeftShift, RightShift, UnsignedRightShift,
// Logical
LogicalAnd, LogicalOr,
// Comparison
Equals, NotEquals, LessThan, LessThanOrEqual, GreaterThan, GreaterThanOrEqual,
// Assignment
Assign, AddAssign, SubtractAssign, MultiplyAssign, DivideAssign, ModuloAssign,
BitwiseAndAssign, BitwiseOrAssign, BitwiseXorAssign,
LeftShiftAssign, RightShiftAssign, UnsignedRightShiftAssign
}
///
/// Represents a unary expression (!a, ++i, etc.).
///
public class UnaryExpression : Expression
{
public UnaryOperator Operator { get; }
public Expression Operand { get; }
public bool IsPrefix { get; }
public UnaryExpression(
SourceRange location,
UnaryOperator @operator,
Expression operand,
bool isPrefix = true) : base(location)
{
Operator = @operator;
Operand = operand;
IsPrefix = isPrefix;
AddChild(operand);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitUnaryExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitUnaryExpression(this);
}
public enum UnaryOperator
{
Plus, Minus, BitwiseNot, LogicalNot,
PreIncrement, PreDecrement, PostIncrement, PostDecrement
}
///
/// Represents a conditional expression (a ? b : c).
///
public class ConditionalExpression : Expression
{
public Expression Condition { get; }
public Expression ThenExpression { get; }
public Expression ElseExpression { get; }
public ConditionalExpression(
SourceRange location,
Expression condition,
Expression thenExpression,
Expression elseExpression) : base(location)
{
Condition = condition;
ThenExpression = thenExpression;
ElseExpression = elseExpression;
AddChild(condition);
AddChild(thenExpression);
AddChild(elseExpression);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitConditionalExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitConditionalExpression(this);
}
///
/// Represents a method call expression.
///
public class MethodCallExpression : Expression
{
public Expression? Target { get; }
public string MethodName { get; }
public IReadOnlyList TypeArguments { get; }
public IReadOnlyList Arguments { get; }
public MethodCallExpression(
SourceRange location,
Expression? target,
string methodName,
IReadOnlyList typeArguments,
IReadOnlyList arguments) : base(location)
{
Target = target;
MethodName = methodName;
TypeArguments = typeArguments;
Arguments = arguments;
if (target != null) AddChild(target);
AddChildren(typeArguments);
AddChildren(arguments);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitMethodCallExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitMethodCallExpression(this);
}
///
/// Represents a field access expression.
///
public class FieldAccessExpression : Expression
{
public Expression Target { get; }
public string FieldName { get; }
public FieldAccessExpression(
SourceRange location,
Expression target,
string fieldName) : base(location)
{
Target = target;
FieldName = fieldName;
AddChild(target);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitFieldAccessExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitFieldAccessExpression(this);
}
///
/// Represents an array access expression.
///
public class ArrayAccessExpression : Expression
{
public Expression Array { get; }
public Expression Index { get; }
public ArrayAccessExpression(
SourceRange location,
Expression array,
Expression index) : base(location)
{
Array = array;
Index = index;
AddChild(array);
AddChild(index);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitArrayAccessExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitArrayAccessExpression(this);
}
///
/// Represents a cast expression.
///
public class CastExpression : Expression
{
public TypeReference Type { get; }
public Expression Expression { get; }
public CastExpression(
SourceRange location,
TypeReference type,
Expression expression) : base(location)
{
Type = type;
Expression = expression;
AddChild(type);
AddChild(expression);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitCastExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitCastExpression(this);
}
///
/// Represents an instanceof expression.
///
public class InstanceOfExpression : Expression
{
public Expression Expression { get; }
public TypeReference Type { get; }
public string? PatternVariable { get; }
public InstanceOfExpression(
SourceRange location,
Expression expression,
TypeReference type,
string? patternVariable = null) : base(location)
{
Expression = expression;
Type = type;
PatternVariable = patternVariable;
AddChild(expression);
AddChild(type);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitInstanceOfExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitInstanceOfExpression(this);
}
///
/// Represents a 'new' expression for object creation.
///
public class NewExpression : Expression
{
public ClassOrInterfaceType Type { get; }
public IReadOnlyList Arguments { get; }
public ClassDeclaration? AnonymousClassBody { get; }
public NewExpression(
SourceRange location,
ClassOrInterfaceType type,
IReadOnlyList arguments,
ClassDeclaration? anonymousClassBody = null) : base(location)
{
Type = type;
Arguments = arguments;
AnonymousClassBody = anonymousClassBody;
AddChild(type);
AddChildren(arguments);
if (anonymousClassBody != null) AddChild(anonymousClassBody);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitNewExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitNewExpression(this);
}
///
/// Represents an array creation expression.
///
public class NewArrayExpression : Expression
{
public TypeReference ElementType { get; }
public IReadOnlyList Dimensions { get; }
public ArrayInitializer? Initializer { get; }
public NewArrayExpression(
SourceRange location,
TypeReference elementType,
IReadOnlyList dimensions,
ArrayInitializer? initializer = null) : base(location)
{
ElementType = elementType;
Dimensions = dimensions;
Initializer = initializer;
AddChild(elementType);
AddChildren(dimensions);
if (initializer != null) AddChild(initializer);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitNewArrayExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitNewArrayExpression(this);
}
///
/// Represents an array initializer.
///
public class ArrayInitializer : Expression
{
public IReadOnlyList Elements { get; }
public ArrayInitializer(
SourceRange location,
IReadOnlyList elements) : base(location)
{
Elements = elements;
AddChildren(elements);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitArrayInitializer(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitArrayInitializer(this);
}
///
/// Represents a lambda expression.
///
public class LambdaExpression : Expression
{
public IReadOnlyList Parameters { get; }
public JavaNode Body { get; } // Can be Expression or BlockStatement
public LambdaExpression(
SourceRange location,
IReadOnlyList parameters,
JavaNode body) : base(location)
{
Parameters = parameters;
Body = body;
AddChildren(parameters);
AddChild(body);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitLambdaExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitLambdaExpression(this);
}
///
/// Represents a lambda parameter.
///
public class LambdaParameter : JavaNode
{
public string Name { get; }
public TypeReference? Type { get; }
public bool IsFinal { get; }
public LambdaParameter(
SourceRange location,
string name,
TypeReference? type = null,
bool isFinal = false) : base(location)
{
Name = name;
Type = type;
IsFinal = isFinal;
if (type != null) AddChild(type);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitLambdaParameter(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitLambdaParameter(this);
}
///
/// Represents a method reference expression (String::length).
///
public class MethodReferenceExpression : Expression
{
public Expression Target { get; }
public string MethodName { get; }
public IReadOnlyList TypeArguments { get; }
public MethodReferenceExpression(
SourceRange location,
Expression target,
string methodName,
IReadOnlyList typeArguments) : base(location)
{
Target = target;
MethodName = methodName;
TypeArguments = typeArguments;
AddChild(target);
AddChildren(typeArguments);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitMethodReferenceExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitMethodReferenceExpression(this);
}
///
/// Represents a class literal expression (String.class).
///
public class ClassLiteralExpression : Expression
{
public TypeReference Type { get; }
public ClassLiteralExpression(SourceRange location, TypeReference type) : base(location)
{
Type = type;
AddChild(type);
}
public override T Accept(IJavaVisitor visitor) => visitor.VisitClassLiteralExpression(this);
public override void Accept(IJavaVisitor visitor) => visitor.VisitClassLiteralExpression(this);
}
}