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); // } }