static JCExpression createFieldAccessor( TreeMaker maker, JavacNode field, FieldAccess fieldAccess, JCExpression receiver) { boolean lookForGetter = lookForGetter(field, fieldAccess); GetterMethod getter = lookForGetter ? findGetter(field) : null; JCVariableDecl fieldDecl = (JCVariableDecl) field.get(); if (getter == null) { if (receiver == null) { if ((fieldDecl.mods.flags & Flags.STATIC) == 0) { receiver = maker.Ident(field.toName("this")); } else { JavacNode containerNode = field.up(); if (containerNode != null && containerNode.get() instanceof JCClassDecl) { JCClassDecl container = (JCClassDecl) field.up().get(); receiver = maker.Ident(container.name); } } } return receiver == null ? maker.Ident(fieldDecl.name) : maker.Select(receiver, fieldDecl.name); } if (receiver == null) receiver = maker.Ident(field.toName("this")); JCMethodInvocation call = maker.Apply( List.<JCExpression>nil(), maker.Select(receiver, getter.name), List.<JCExpression>nil()); return call; }
/** * In javac, dotted access of any kind, from {@code java.lang.String} to {@code var.methodName} is * represented by a fold-left of {@code Select} nodes with the leftmost string represented by a * {@code Ident} node. This method generates such an expression. * * <p>The position of the generated node(s) will be equal to the {@code pos} parameter. * * <p>For example, maker.Select(maker.Select(maker.Ident(NAME[java]), NAME[lang]), NAME[String]). * * @see com.sun.tools.javac.tree.JCTree.JCIdent * @see com.sun.tools.javac.tree.JCTree.JCFieldAccess */ public static JCExpression chainDots(JavacNode node, int pos, String... elems) { assert elems != null; assert elems.length > 0; TreeMaker maker = node.getTreeMaker(); if (pos != -1) maker = maker.at(pos); JCExpression e = maker.Ident(node.toName(elems[0])); for (int i = 1; i < elems.length; i++) { e = maker.Select(e, node.toName(elems[i])); } return e; }
private static JCExpression cloneType0(TreeMaker maker, JCTree in) { if (in == null) return null; if (in instanceof JCPrimitiveTypeTree) return (JCExpression) in; if (in instanceof JCIdent) { return maker.Ident(((JCIdent) in).name); } if (in instanceof JCFieldAccess) { JCFieldAccess fa = (JCFieldAccess) in; return maker.Select(cloneType0(maker, fa.selected), fa.name); } if (in instanceof JCArrayTypeTree) { JCArrayTypeTree att = (JCArrayTypeTree) in; return maker.TypeArray(cloneType0(maker, att.elemtype)); } if (in instanceof JCTypeApply) { JCTypeApply ta = (JCTypeApply) in; ListBuffer<JCExpression> lb = ListBuffer.lb(); for (JCExpression typeArg : ta.arguments) { lb.append(cloneType0(maker, typeArg)); } return maker.TypeApply(cloneType0(maker, ta.clazz), lb.toList()); } if (in instanceof JCWildcard) { JCWildcard w = (JCWildcard) in; JCExpression newInner = cloneType0(maker, w.inner); TypeBoundKind newKind; switch (w.getKind()) { case SUPER_WILDCARD: newKind = maker.TypeBoundKind(BoundKind.SUPER); break; case EXTENDS_WILDCARD: newKind = maker.TypeBoundKind(BoundKind.EXTENDS); break; default: case UNBOUNDED_WILDCARD: newKind = maker.TypeBoundKind(BoundKind.UNBOUND); break; } return maker.Wildcard(newKind, newInner); } // This is somewhat unsafe, but it's better than outright throwing an exception here. Returning // null will just cause an exception down the pipeline. return (JCExpression) in; }