package com.ochafik.lang.jnaerator.parser;
import static com.ochafik.lang.jnaerator.parser.Expression.*;
import java.util.Arrays;
import static com.ochafik.lang.jnaerator.parser.Identifier.*;
import static com.ochafik.lang.jnaerator.parser.Statement.*;
import com.ochafik.lang.jnaerator.parser.Expression.Constant;
import com.ochafik.lang.jnaerator.parser.Expression.MemberRefStyle;
import com.ochafik.lang.jnaerator.parser.TypeRef.SimpleTypeRef;
import com.ochafik.lang.jnaerator.parser.TypeRef.TaggedTypeRef;
import java.util.ArrayList;
import java.util.List;
public class ElementsHelper {
public static Expression classLiteral(Class<?> c) {
if (c == null) {
return null;
}
if (c.isPrimitive()) {
if (c == Integer.TYPE) {
c = Integer.class;
} else if (c == Long.TYPE) {
c = Long.class;
} else if (c == Short.TYPE) {
c = Short.class;
} else if (c == Byte.TYPE) {
c = Byte.class;
} else if (c == Character.TYPE) {
c = Character.class;
} else if (c == Boolean.TYPE) {
c = Boolean.class;
} else if (c == Float.TYPE) {
c = Float.class;
} else if (c == Double.TYPE) {
c = Double.class;
}
return staticField(c, "TYPE");
}
return staticField(c, "class");
}
public static Expression staticField(Class<?> c, String name) {
return memberRef(expr(typeRef(ident(c))), MemberRefStyle.Dot, name);
}
public static Expression thisField(String name) {
return memberRef(thisRef(), MemberRefStyle.Dot, name);
}
public static Expression thisRef() {
return varRef("this");
}
public static Expression memberRef(Expression x, String name) {
return memberRef(x, MemberRefStyle.Dot, name);
}
public static Expression memberRef(Expression x, MemberRefStyle style, String name) {
return memberRef(x, style, ident(name));
}
public static Expression memberRef(Expression x, MemberRefStyle style, Identifier name) {
return new Expression.MemberRef(x, style, name);
}
public static Expression memberRef(Expression x, Identifier name) {
return memberRef(x, MemberRefStyle.Dot, name);
}
public static Expression varRef(String name) {
return new Expression.VariableRef(new SimpleIdentifier(name));
}
public static Expression varRef(SimpleIdentifier name) {
return new Expression.VariableRef(name);
}
public static Expression varRef(Identifier name) {
MemberRefStyle s = MemberRefStyle.Dot;
if (name instanceof QualifiedIdentifier) {
QualificationSeparator sep = ((QualifiedIdentifier) name).getSeparator();
if (sep == QualificationSeparator.Colons) {
s = MemberRefStyle.Colons;
}
}
if (name instanceof SimpleIdentifier) {
return varRef((SimpleIdentifier) name);
}
return memberRef(expr(typeRef(name.resolveAllButLastIdentifier())), s, name.resolveLastSimpleIdentifier());
}
public static Expression enumRef(java.lang.Enum e) {
return memberRef(expr(typeRef(e.getDeclaringClass())), e.name());
}
public static Identifier ident(QualificationSeparator separator, String... components) {
if (components == null) {
return null;
}
List<SimpleIdentifier> list = new ArrayList<SimpleIdentifier>();
for (String o : components) {
if (o != null && (o = o.trim()).length() > 0) {
for (String elt : o.split("\\.|::")) {
list.add(new SimpleIdentifier(elt));
}
}
}
if (list.isEmpty()) {
return null;
}
if (list.size() == 1) {
return list.get(0);
}
QualifiedIdentifier id = new QualifiedIdentifier(separator);
id.setIdentifiers(list);
return id;
}
public static Identifier ident(String... components) {
return ident(QualificationSeparator.Dot, components);
}
public static List<SimpleIdentifier> getClassSimpleIdentifiers(String className) {
List<SimpleIdentifier> elts = new ArrayList<SimpleIdentifier>();
for (String s : className.split("[.$]")) {
if (s.length() > 0) {
elts.add(new SimpleIdentifier(s));
}
}
return elts;
}
public static Identifier ident(Class<?> cl, Expression... args) {
if (cl == null) {
return null;
}
if (cl == Void.TYPE || cl == Void.class) {
return ident("void");
}
QualifiedIdentifier id = new QualifiedIdentifier(QualificationSeparator.Dot);
id.setIdentifiers(getClassSimpleIdentifiers(cl.getName()));
id.resolveLastSimpleIdentifier().setTemplateArguments(Arrays.asList(args));
return id;
}
public static Identifier templateIdent(Identifier base, Expression... args) {
Identifier id = base.clone();
id.resolveLastSimpleIdentifier().setTemplateArguments(Arrays.asList(args));
return id;
}
public static Identifier ident(Identifier ident, String name) {
return ident(ident, ident(name));
}
public static Identifier ident(Identifier ident, Identifier... others) {
if (ident == null) {
if (others.length > 0) {
return ident(others[0], Arrays.copyOfRange(others, 1, others.length));
}
return null;
}
return ident.derive(Identifier.QualificationSeparator.Dot, others);
}
public static Expression opaqueExpr(String s) {
return new OpaqueExpression(s);
}
public static Expression cast(TypeRef t, Expression s) {
return new Cast(t, s);
}
public static Expression nullExpr() {
return new NullExpression();
}
public static Expression expr(TypeRef tr) {
return new TypeRefExpression(tr);
}
public static Expression expr(boolean c) {
return expr(Constant.Type.Bool, c);
}
public static Expression expr(double c) {
return expr(Constant.Type.Double, c);
}
public static Expression expr(int c) {
return expr(Constant.Type.Int, c);
}
public static Expression expr(String c) {
return expr(Constant.Type.String, c);
}
public static Expression expr(Constant.Type type, Object value) {
return new Constant(type, value, null);
}
public static Expression expr(UnaryOperator op, Expression b) {
return new UnaryOp(b, op).setParenthesis(true);
}
public static Expression expr(Expression a, BinaryOperator op, Expression b) {
return new BinaryOp(a, op, b).setParenthesis(true);
}
public static Expression expr(Expression a, AssignmentOperator op, Expression b) {
return new AssignmentOp(a, op, b);
}
@SuppressWarnings("unchecked")
public static <T extends Element> List<T> clones(List<T> list) {
List<T> clone = new ArrayList<T>(list.size());
for (T e : list) {
clone.add((T) e.clone());
}
return clone;
}
public static FunctionCall methodCall(Expression x, MemberRefStyle style, String name, Expression... exprs) {
return new FunctionCall(memberRef(x, style, name), exprs);
}
public static FunctionCall methodCall(Expression x, MemberRefStyle style, Identifier name, Expression... exprs) {
return new FunctionCall(memberRef(x, style, name), exprs);
}
// Given Pointer<T>, returns T
public static TypeRef getSingleTypeParameter(TypeRef tr) {
if (!(tr instanceof SimpleTypeRef)) {
return null;
}
SimpleTypeRef str = (SimpleTypeRef) tr;
Identifier name = str.getName();
if (name == null) {
return null;
}
SimpleIdentifier id = name.resolveLastSimpleIdentifier();
List<Expression> templateArguments = id.getTemplateArguments();
if (templateArguments.size() != 1) {
return null;
}
Expression x = templateArguments.get(0);
if (!(x instanceof TypeRefExpression)) {
return null;
}
return ((TypeRefExpression) x).getType();
}
public static FunctionCall methodCall(Expression x, String name, Expression... exprs) {
return methodCall(x, MemberRefStyle.Dot, name, exprs);
}
public static FunctionCall methodCall(Identifier name, Expression... exprs) {
return new FunctionCall(memberRef(null, null, name), exprs);
}
public static FunctionCall methodCall(String name, Expression... exprs) {
return methodCall(ident(name), exprs);
}
public static TypeRef typeRef(Class<?> cl) {
if (cl == null) {
return null;
}
if (cl.isArray()) {
return new TypeRef.ArrayRef(typeRef(cl.getComponentType()));
}
if (cl.isPrimitive() || cl == Void.class) {
return new TypeRef.Primitive(cl.getSimpleName());
}
return typeRef(ident(cl));
}
public static SimpleTypeRef typeRef(String name) {
return typeRef(ident(name));
}
public static SimpleTypeRef typeRef(Identifier name) {
return name == null ? null : new SimpleTypeRef(name);
}
public static TypeRef subType(SimpleTypeRef tr, Identifier name) {
return typeRef(ident(tr.getName(), name));
}
public static Statement stat(Declaration d) {
return d;//new Statement.DeclarationStatement(d);
}
public static Statement tryRethrow(Statement st) {
String exName = "$ex$";
return new Try(st, null, new Catch(new VariablesDeclaration(typeRef(Throwable.class), new Declarator.DirectDeclarator(exName)), new Throw(new New(typeRef(RuntimeException.class), varRef(exName)))));
}
public static Statement stat(Expression x) {
return new ExpressionStatement(x);
}
public static Declaration decl(Statement stat) {
return new StatementDeclaration(stat);
}
public static Statement stat(TypeRef tr, String varName, Expression ass) {
VariablesDeclaration vd = new VariablesDeclaration(tr, new Declarator.DirectDeclarator(varName, ass));
return vd;//new Statement.DeclarationStatement(vd);
}
public static Block block(Statement... x) {
return new Block(x);
}
public static TaggedTypeRefDeclaration decl(TaggedTypeRef tr) {
return tr == null ? null : new TaggedTypeRefDeclaration(tr);
}
/*
public static TypeRef typeRef(TypeRef parentTypeRef, Style style, Identifier subName) {
if (parentTypeRef == null)
return typeRef(subName);
return new SubTypeRef(parentTypeRef, style, subName);
}*/
// public static TypeRef typeRef(TypeRef parentTypeRef, String subName) {
// return typeRef(parentTypeRef, Style.Dot, subName);
// }
}