Home » openjdk-7 » com.sun.tools » javac » tree » [javadoc | source]

    1   /*
    2    * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package com.sun.tools.javac.tree;
   27   
   28   import com.sun.tools.javac.code;
   29   import com.sun.tools.javac.code.Symbol;
   30   import com.sun.tools.javac.code.Type;
   31   import com.sun.tools.javac.util;
   32   import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
   33   
   34   import com.sun.tools.javac.tree.JCTree;
   35   
   36   import static com.sun.tools.javac.code.Flags.*;
   37   import static com.sun.tools.javac.code.Kinds.*;
   38   import static com.sun.tools.javac.code.TypeTags.*;
   39   
   40   /** Factory class for trees.
   41    *
   42    *  <p><b>This is NOT part of any supported API.
   43    *  If you write code that depends on this, you do so at your own risk.
   44    *  This code and its internal interfaces are subject to change or
   45    *  deletion without notice.</b>
   46    */
   47   public class TreeMaker implements JCTree.Factory {
   48   
   49       /** The context key for the tree factory. */
   50       protected static final Context.Key<TreeMaker> treeMakerKey =
   51           new Context.Key<TreeMaker>();
   52   
   53       /** Get the TreeMaker instance. */
   54       public static TreeMaker instance(Context context) {
   55           TreeMaker instance = context.get(treeMakerKey);
   56           if (instance == null)
   57               instance = new TreeMaker(context);
   58           return instance;
   59       }
   60   
   61       /** The position at which subsequent trees will be created.
   62        */
   63       public int pos = Position.NOPOS;
   64   
   65       /** The toplevel tree to which created trees belong.
   66        */
   67       public JCCompilationUnit toplevel;
   68   
   69       /** The current name table. */
   70       Names names;
   71   
   72       Types types;
   73   
   74       /** The current symbol table. */
   75       Symtab syms;
   76   
   77       /** Create a tree maker with null toplevel and NOPOS as initial position.
   78        */
   79       protected TreeMaker(Context context) {
   80           context.put(treeMakerKey, this);
   81           this.pos = Position.NOPOS;
   82           this.toplevel = null;
   83           this.names = Names.instance(context);
   84           this.syms = Symtab.instance(context);
   85           this.types = Types.instance(context);
   86       }
   87   
   88       /** Create a tree maker with a given toplevel and FIRSTPOS as initial position.
   89        */
   90       TreeMaker(JCCompilationUnit toplevel, Names names, Types types, Symtab syms) {
   91           this.pos = Position.FIRSTPOS;
   92           this.toplevel = toplevel;
   93           this.names = names;
   94           this.types = types;
   95           this.syms = syms;
   96       }
   97   
   98       /** Create a new tree maker for a given toplevel.
   99        */
  100       public TreeMaker forToplevel(JCCompilationUnit toplevel) {
  101           return new TreeMaker(toplevel, names, types, syms);
  102       }
  103   
  104       /** Reassign current position.
  105        */
  106       public TreeMaker at(int pos) {
  107           this.pos = pos;
  108           return this;
  109       }
  110   
  111       /** Reassign current position.
  112        */
  113       public TreeMaker at(DiagnosticPosition pos) {
  114           this.pos = (pos == null ? Position.NOPOS : pos.getStartPosition());
  115           return this;
  116       }
  117   
  118       /**
  119        * Create given tree node at current position.
  120        * @param defs a list of ClassDef, Import, and Skip
  121        */
  122       public JCCompilationUnit TopLevel(List<JCAnnotation> packageAnnotations,
  123                                         JCExpression pid,
  124                                         List<JCTree> defs) {
  125           Assert.checkNonNull(packageAnnotations);
  126           for (JCTree node : defs)
  127               Assert.check(node instanceof JCClassDecl
  128                   || node instanceof JCImport
  129                   || node instanceof JCSkip
  130                   || node instanceof JCErroneous
  131                   || (node instanceof JCExpressionStatement
  132                       && ((JCExpressionStatement)node).expr instanceof JCErroneous),
  133                   node.getClass().getSimpleName());
  134           JCCompilationUnit tree = new JCCompilationUnit(packageAnnotations, pid, defs,
  135                                        null, null, null, null);
  136           tree.pos = pos;
  137           return tree;
  138       }
  139   
  140       public JCImport Import(JCTree qualid, boolean importStatic) {
  141           JCImport tree = new JCImport(qualid, importStatic);
  142           tree.pos = pos;
  143           return tree;
  144       }
  145   
  146       public JCClassDecl ClassDef(JCModifiers mods,
  147                                   Name name,
  148                                   List<JCTypeParameter> typarams,
  149                                   JCExpression extending,
  150                                   List<JCExpression> implementing,
  151                                   List<JCTree> defs)
  152       {
  153           JCClassDecl tree = new JCClassDecl(mods,
  154                                        name,
  155                                        typarams,
  156                                        extending,
  157                                        implementing,
  158                                        defs,
  159                                        null);
  160           tree.pos = pos;
  161           return tree;
  162       }
  163   
  164       public JCMethodDecl MethodDef(JCModifiers mods,
  165                                  Name name,
  166                                  JCExpression restype,
  167                                  List<JCTypeParameter> typarams,
  168                                  List<JCVariableDecl> params,
  169                                  List<JCExpression> thrown,
  170                                  JCBlock body,
  171                                  JCExpression defaultValue) {
  172           JCMethodDecl tree = new JCMethodDecl(mods,
  173                                          name,
  174                                          restype,
  175                                          typarams,
  176                                          params,
  177                                          thrown,
  178                                          body,
  179                                          defaultValue,
  180                                          null);
  181           tree.pos = pos;
  182           return tree;
  183       }
  184   
  185       public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init) {
  186           JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, null);
  187           tree.pos = pos;
  188           return tree;
  189       }
  190   
  191       public JCSkip Skip() {
  192           JCSkip tree = new JCSkip();
  193           tree.pos = pos;
  194           return tree;
  195       }
  196   
  197       public JCBlock Block(long flags, List<JCStatement> stats) {
  198           JCBlock tree = new JCBlock(flags, stats);
  199           tree.pos = pos;
  200           return tree;
  201       }
  202   
  203       public JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond) {
  204           JCDoWhileLoop tree = new JCDoWhileLoop(body, cond);
  205           tree.pos = pos;
  206           return tree;
  207       }
  208   
  209       public JCWhileLoop WhileLoop(JCExpression cond, JCStatement body) {
  210           JCWhileLoop tree = new JCWhileLoop(cond, body);
  211           tree.pos = pos;
  212           return tree;
  213       }
  214   
  215       public JCForLoop ForLoop(List<JCStatement> init,
  216                              JCExpression cond,
  217                              List<JCExpressionStatement> step,
  218                              JCStatement body)
  219       {
  220           JCForLoop tree = new JCForLoop(init, cond, step, body);
  221           tree.pos = pos;
  222           return tree;
  223       }
  224   
  225       public JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body) {
  226           JCEnhancedForLoop tree = new JCEnhancedForLoop(var, expr, body);
  227           tree.pos = pos;
  228           return tree;
  229       }
  230   
  231       public JCLabeledStatement Labelled(Name label, JCStatement body) {
  232           JCLabeledStatement tree = new JCLabeledStatement(label, body);
  233           tree.pos = pos;
  234           return tree;
  235       }
  236   
  237       public JCSwitch Switch(JCExpression selector, List<JCCase> cases) {
  238           JCSwitch tree = new JCSwitch(selector, cases);
  239           tree.pos = pos;
  240           return tree;
  241       }
  242   
  243       public JCCase Case(JCExpression pat, List<JCStatement> stats) {
  244           JCCase tree = new JCCase(pat, stats);
  245           tree.pos = pos;
  246           return tree;
  247       }
  248   
  249       public JCSynchronized Synchronized(JCExpression lock, JCBlock body) {
  250           JCSynchronized tree = new JCSynchronized(lock, body);
  251           tree.pos = pos;
  252           return tree;
  253       }
  254   
  255       public JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) {
  256           return Try(List.<JCTree>nil(), body, catchers, finalizer);
  257       }
  258   
  259       public JCTry Try(List<JCTree> resources,
  260                        JCBlock body,
  261                        List<JCCatch> catchers,
  262                        JCBlock finalizer) {
  263           JCTry tree = new JCTry(resources, body, catchers, finalizer);
  264           tree.pos = pos;
  265           return tree;
  266       }
  267   
  268       public JCCatch Catch(JCVariableDecl param, JCBlock body) {
  269           JCCatch tree = new JCCatch(param, body);
  270           tree.pos = pos;
  271           return tree;
  272       }
  273   
  274       public JCConditional Conditional(JCExpression cond,
  275                                      JCExpression thenpart,
  276                                      JCExpression elsepart)
  277       {
  278           JCConditional tree = new JCConditional(cond, thenpart, elsepart);
  279           tree.pos = pos;
  280           return tree;
  281       }
  282   
  283       public JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart) {
  284           JCIf tree = new JCIf(cond, thenpart, elsepart);
  285           tree.pos = pos;
  286           return tree;
  287       }
  288   
  289       public JCExpressionStatement Exec(JCExpression expr) {
  290           JCExpressionStatement tree = new JCExpressionStatement(expr);
  291           tree.pos = pos;
  292           return tree;
  293       }
  294   
  295       public JCBreak Break(Name label) {
  296           JCBreak tree = new JCBreak(label, null);
  297           tree.pos = pos;
  298           return tree;
  299       }
  300   
  301       public JCContinue Continue(Name label) {
  302           JCContinue tree = new JCContinue(label, null);
  303           tree.pos = pos;
  304           return tree;
  305       }
  306   
  307       public JCReturn Return(JCExpression expr) {
  308           JCReturn tree = new JCReturn(expr);
  309           tree.pos = pos;
  310           return tree;
  311       }
  312   
  313       public JCThrow Throw(JCTree expr) {
  314           JCThrow tree = new JCThrow(expr);
  315           tree.pos = pos;
  316           return tree;
  317       }
  318   
  319       public JCAssert Assert(JCExpression cond, JCExpression detail) {
  320           JCAssert tree = new JCAssert(cond, detail);
  321           tree.pos = pos;
  322           return tree;
  323       }
  324   
  325       public JCMethodInvocation Apply(List<JCExpression> typeargs,
  326                          JCExpression fn,
  327                          List<JCExpression> args)
  328       {
  329           JCMethodInvocation tree = new JCMethodInvocation(typeargs, fn, args);
  330           tree.pos = pos;
  331           return tree;
  332       }
  333   
  334       public JCNewClass NewClass(JCExpression encl,
  335                                List<JCExpression> typeargs,
  336                                JCExpression clazz,
  337                                List<JCExpression> args,
  338                                JCClassDecl def)
  339       {
  340           JCNewClass tree = new JCNewClass(encl, typeargs, clazz, args, def);
  341           tree.pos = pos;
  342           return tree;
  343       }
  344   
  345       public JCNewArray NewArray(JCExpression elemtype,
  346                                List<JCExpression> dims,
  347                                List<JCExpression> elems)
  348       {
  349           JCNewArray tree = new JCNewArray(elemtype, dims, elems);
  350           tree.pos = pos;
  351           return tree;
  352       }
  353   
  354       public JCParens Parens(JCExpression expr) {
  355           JCParens tree = new JCParens(expr);
  356           tree.pos = pos;
  357           return tree;
  358       }
  359   
  360       public JCAssign Assign(JCExpression lhs, JCExpression rhs) {
  361           JCAssign tree = new JCAssign(lhs, rhs);
  362           tree.pos = pos;
  363           return tree;
  364       }
  365   
  366       public JCAssignOp Assignop(int opcode, JCTree lhs, JCTree rhs) {
  367           JCAssignOp tree = new JCAssignOp(opcode, lhs, rhs, null);
  368           tree.pos = pos;
  369           return tree;
  370       }
  371   
  372       public JCUnary Unary(int opcode, JCExpression arg) {
  373           JCUnary tree = new JCUnary(opcode, arg);
  374           tree.pos = pos;
  375           return tree;
  376       }
  377   
  378       public JCBinary Binary(int opcode, JCExpression lhs, JCExpression rhs) {
  379           JCBinary tree = new JCBinary(opcode, lhs, rhs, null);
  380           tree.pos = pos;
  381           return tree;
  382       }
  383   
  384       public JCTypeCast TypeCast(JCTree clazz, JCExpression expr) {
  385           JCTypeCast tree = new JCTypeCast(clazz, expr);
  386           tree.pos = pos;
  387           return tree;
  388       }
  389   
  390       public JCInstanceOf TypeTest(JCExpression expr, JCTree clazz) {
  391           JCInstanceOf tree = new JCInstanceOf(expr, clazz);
  392           tree.pos = pos;
  393           return tree;
  394       }
  395   
  396       public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) {
  397           JCArrayAccess tree = new JCArrayAccess(indexed, index);
  398           tree.pos = pos;
  399           return tree;
  400       }
  401   
  402       public JCFieldAccess Select(JCExpression selected, Name selector) {
  403           JCFieldAccess tree = new JCFieldAccess(selected, selector, null);
  404           tree.pos = pos;
  405           return tree;
  406       }
  407   
  408       public JCIdent Ident(Name name) {
  409           JCIdent tree = new JCIdent(name, null);
  410           tree.pos = pos;
  411           return tree;
  412       }
  413   
  414       public JCLiteral Literal(int tag, Object value) {
  415           JCLiteral tree = new JCLiteral(tag, value);
  416           tree.pos = pos;
  417           return tree;
  418       }
  419   
  420       public JCPrimitiveTypeTree TypeIdent(int typetag) {
  421           JCPrimitiveTypeTree tree = new JCPrimitiveTypeTree(typetag);
  422           tree.pos = pos;
  423           return tree;
  424       }
  425   
  426       public JCArrayTypeTree TypeArray(JCExpression elemtype) {
  427           JCArrayTypeTree tree = new JCArrayTypeTree(elemtype);
  428           tree.pos = pos;
  429           return tree;
  430       }
  431   
  432       public JCTypeApply TypeApply(JCExpression clazz, List<JCExpression> arguments) {
  433           JCTypeApply tree = new JCTypeApply(clazz, arguments);
  434           tree.pos = pos;
  435           return tree;
  436       }
  437   
  438       public JCTypeUnion TypeUnion(List<JCExpression> components) {
  439           JCTypeUnion tree = new JCTypeUnion(components);
  440           tree.pos = pos;
  441           return tree;
  442       }
  443   
  444       public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) {
  445           JCTypeParameter tree = new JCTypeParameter(name, bounds);
  446           tree.pos = pos;
  447           return tree;
  448       }
  449   
  450       public JCWildcard Wildcard(TypeBoundKind kind, JCTree type) {
  451           JCWildcard tree = new JCWildcard(kind, type);
  452           tree.pos = pos;
  453           return tree;
  454       }
  455   
  456       public TypeBoundKind TypeBoundKind(BoundKind kind) {
  457           TypeBoundKind tree = new TypeBoundKind(kind);
  458           tree.pos = pos;
  459           return tree;
  460       }
  461   
  462       public JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args) {
  463           JCAnnotation tree = new JCAnnotation(annotationType, args);
  464           tree.pos = pos;
  465           return tree;
  466       }
  467   
  468       public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) {
  469           JCModifiers tree = new JCModifiers(flags, annotations);
  470           boolean noFlags = (flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0;
  471           tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS : pos;
  472           return tree;
  473       }
  474   
  475       public JCModifiers Modifiers(long flags) {
  476           return Modifiers(flags, List.<JCAnnotation>nil());
  477       }
  478   
  479       public JCErroneous Erroneous() {
  480           return Erroneous(List.<JCTree>nil());
  481       }
  482   
  483       public JCErroneous Erroneous(List<? extends JCTree> errs) {
  484           JCErroneous tree = new JCErroneous(errs);
  485           tree.pos = pos;
  486           return tree;
  487       }
  488   
  489       public LetExpr LetExpr(List<JCVariableDecl> defs, JCTree expr) {
  490           LetExpr tree = new LetExpr(defs, expr);
  491           tree.pos = pos;
  492           return tree;
  493       }
  494   
  495   /* ***************************************************************************
  496    * Derived building blocks.
  497    ****************************************************************************/
  498   
  499       public JCClassDecl AnonymousClassDef(JCModifiers mods,
  500                                            List<JCTree> defs)
  501       {
  502           return ClassDef(mods,
  503                           names.empty,
  504                           List.<JCTypeParameter>nil(),
  505                           null,
  506                           List.<JCExpression>nil(),
  507                           defs);
  508       }
  509   
  510       public LetExpr LetExpr(JCVariableDecl def, JCTree expr) {
  511           LetExpr tree = new LetExpr(List.of(def), expr);
  512           tree.pos = pos;
  513           return tree;
  514       }
  515   
  516       /** Create an identifier from a symbol.
  517        */
  518       public JCIdent Ident(Symbol sym) {
  519           return (JCIdent)new JCIdent((sym.name != names.empty)
  520                                   ? sym.name
  521                                   : sym.flatName(), sym)
  522               .setPos(pos)
  523               .setType(sym.type);
  524       }
  525   
  526       /** Create a selection node from a qualifier tree and a symbol.
  527        *  @param base   The qualifier tree.
  528        */
  529       public JCExpression Select(JCExpression base, Symbol sym) {
  530           return new JCFieldAccess(base, sym.name, sym).setPos(pos).setType(sym.type);
  531       }
  532   
  533       /** Create a qualified identifier from a symbol, adding enough qualifications
  534        *  to make the reference unique.
  535        */
  536       public JCExpression QualIdent(Symbol sym) {
  537           return isUnqualifiable(sym)
  538               ? Ident(sym)
  539               : Select(QualIdent(sym.owner), sym);
  540       }
  541   
  542       /** Create an identifier that refers to the variable declared in given variable
  543        *  declaration.
  544        */
  545       public JCExpression Ident(JCVariableDecl param) {
  546           return Ident(param.sym);
  547       }
  548   
  549       /** Create a list of identifiers referring to the variables declared
  550        *  in given list of variable declarations.
  551        */
  552       public List<JCExpression> Idents(List<JCVariableDecl> params) {
  553           ListBuffer<JCExpression> ids = new ListBuffer<JCExpression>();
  554           for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail)
  555               ids.append(Ident(l.head));
  556           return ids.toList();
  557       }
  558   
  559       /** Create a tree representing `this', given its type.
  560        */
  561       public JCExpression This(Type t) {
  562           return Ident(new VarSymbol(FINAL, names._this, t, t.tsym));
  563       }
  564   
  565       /** Create a tree representing a class literal.
  566        */
  567       public JCExpression ClassLiteral(ClassSymbol clazz) {
  568           return ClassLiteral(clazz.type);
  569       }
  570   
  571       /** Create a tree representing a class literal.
  572        */
  573       public JCExpression ClassLiteral(Type t) {
  574           VarSymbol lit = new VarSymbol(STATIC | PUBLIC | FINAL,
  575                                         names._class,
  576                                         t,
  577                                         t.tsym);
  578           return Select(Type(t), lit);
  579       }
  580   
  581       /** Create a tree representing `super', given its type and owner.
  582        */
  583       public JCIdent Super(Type t, TypeSymbol owner) {
  584           return Ident(new VarSymbol(FINAL, names._super, t, owner));
  585       }
  586   
  587       /**
  588        * Create a method invocation from a method tree and a list of
  589        * argument trees.
  590        */
  591       public JCMethodInvocation App(JCExpression meth, List<JCExpression> args) {
  592           return Apply(null, meth, args).setType(meth.type.getReturnType());
  593       }
  594   
  595       /**
  596        * Create a no-arg method invocation from a method tree
  597        */
  598       public JCMethodInvocation App(JCExpression meth) {
  599           return Apply(null, meth, List.<JCExpression>nil()).setType(meth.type.getReturnType());
  600       }
  601   
  602       /** Create a method invocation from a method tree and a list of argument trees.
  603        */
  604       public JCExpression Create(Symbol ctor, List<JCExpression> args) {
  605           Type t = ctor.owner.erasure(types);
  606           JCNewClass newclass = NewClass(null, null, Type(t), args, null);
  607           newclass.constructor = ctor;
  608           newclass.setType(t);
  609           return newclass;
  610       }
  611   
  612       /** Create a tree representing given type.
  613        */
  614       public JCExpression Type(Type t) {
  615           if (t == null) return null;
  616           JCExpression tp;
  617           switch (t.tag) {
  618           case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
  619           case DOUBLE: case BOOLEAN: case VOID:
  620               tp = TypeIdent(t.tag);
  621               break;
  622           case TYPEVAR:
  623               tp = Ident(t.tsym);
  624               break;
  625           case WILDCARD: {
  626               WildcardType a = ((WildcardType) t);
  627               tp = Wildcard(TypeBoundKind(a.kind), Type(a.type));
  628               break;
  629           }
  630           case CLASS:
  631               Type outer = t.getEnclosingType();
  632               JCExpression clazz = outer.tag == CLASS && t.tsym.owner.kind == TYP
  633                   ? Select(Type(outer), t.tsym)
  634                   : QualIdent(t.tsym);
  635               tp = t.getTypeArguments().isEmpty()
  636                   ? clazz
  637                   : TypeApply(clazz, Types(t.getTypeArguments()));
  638               break;
  639           case ARRAY:
  640               tp = TypeArray(Type(types.elemtype(t)));
  641               break;
  642           case ERROR:
  643               tp = TypeIdent(ERROR);
  644               break;
  645           default:
  646               throw new AssertionError("unexpected type: " + t);
  647           }
  648           return tp.setType(t);
  649       }
  650   
  651       /** Create a list of trees representing given list of types.
  652        */
  653       public List<JCExpression> Types(List<Type> ts) {
  654           ListBuffer<JCExpression> lb = new ListBuffer<JCExpression>();
  655           for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
  656               lb.append(Type(l.head));
  657           return lb.toList();
  658       }
  659   
  660       /** Create a variable definition from a variable symbol and an initializer
  661        *  expression.
  662        */
  663       public JCVariableDecl VarDef(VarSymbol v, JCExpression init) {
  664           return (JCVariableDecl)
  665               new JCVariableDecl(
  666                   Modifiers(v.flags(), Annotations(v.getAnnotationMirrors())),
  667                   v.name,
  668                   Type(v.type),
  669                   init,
  670                   v).setPos(pos).setType(v.type);
  671       }
  672   
  673       /** Create annotation trees from annotations.
  674        */
  675       public List<JCAnnotation> Annotations(List<Attribute.Compound> attributes) {
  676           if (attributes == null) return List.nil();
  677           ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
  678           for (List<Attribute.Compound> i = attributes; i.nonEmpty(); i=i.tail) {
  679               Attribute a = i.head;
  680               result.append(Annotation(a));
  681           }
  682           return result.toList();
  683       }
  684   
  685       public JCLiteral Literal(Object value) {
  686           JCLiteral result = null;
  687           if (value instanceof String) {
  688               result = Literal(CLASS, value).
  689                   setType(syms.stringType.constType(value));
  690           } else if (value instanceof Integer) {
  691               result = Literal(INT, value).
  692                   setType(syms.intType.constType(value));
  693           } else if (value instanceof Long) {
  694               result = Literal(LONG, value).
  695                   setType(syms.longType.constType(value));
  696           } else if (value instanceof Byte) {
  697               result = Literal(BYTE, value).
  698                   setType(syms.byteType.constType(value));
  699           } else if (value instanceof Character) {
  700               int v = (int) (((Character) value).toString().charAt(0));
  701               result = Literal(CHAR, value).
  702                   setType(syms.charType.constType(v));
  703           } else if (value instanceof Double) {
  704               result = Literal(DOUBLE, value).
  705                   setType(syms.doubleType.constType(value));
  706           } else if (value instanceof Float) {
  707               result = Literal(FLOAT, value).
  708                   setType(syms.floatType.constType(value));
  709           } else if (value instanceof Short) {
  710               result = Literal(SHORT, value).
  711                   setType(syms.shortType.constType(value));
  712           } else if (value instanceof Boolean) {
  713               int v = ((Boolean) value) ? 1 : 0;
  714               result = Literal(BOOLEAN, v).
  715                   setType(syms.booleanType.constType(v));
  716           } else {
  717               throw new AssertionError(value);
  718           }
  719           return result;
  720       }
  721   
  722       class AnnotationBuilder implements Attribute.Visitor {
  723           JCExpression result = null;
  724           public void visitConstant(Attribute.Constant v) {
  725               result = Literal(v.value);
  726           }
  727           public void visitClass(Attribute.Class clazz) {
  728               result = ClassLiteral(clazz.type).setType(syms.classType);
  729           }
  730           public void visitEnum(Attribute.Enum e) {
  731               result = QualIdent(e.value);
  732           }
  733           public void visitError(Attribute.Error e) {
  734               result = Erroneous();
  735           }
  736           public void visitCompound(Attribute.Compound compound) {
  737               result = visitCompoundInternal(compound);
  738           }
  739           public JCAnnotation visitCompoundInternal(Attribute.Compound compound) {
  740               ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
  741               for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) {
  742                   Pair<MethodSymbol,Attribute> pair = values.head;
  743                   JCExpression valueTree = translate(pair.snd);
  744                   args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type));
  745               }
  746               return Annotation(Type(compound.type), args.toList());
  747           }
  748           public void visitArray(Attribute.Array array) {
  749               ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
  750               for (int i = 0; i < array.values.length; i++)
  751                   elems.append(translate(array.values[i]));
  752               result = NewArray(null, List.<JCExpression>nil(), elems.toList()).setType(array.type);
  753           }
  754           JCExpression translate(Attribute a) {
  755               a.accept(this);
  756               return result;
  757           }
  758           JCAnnotation translate(Attribute.Compound a) {
  759               return visitCompoundInternal(a);
  760           }
  761       }
  762       AnnotationBuilder annotationBuilder = new AnnotationBuilder();
  763   
  764       /** Create an annotation tree from an attribute.
  765        */
  766       public JCAnnotation Annotation(Attribute a) {
  767           return annotationBuilder.translate((Attribute.Compound)a);
  768       }
  769   
  770       /** Create a method definition from a method symbol and a method body.
  771        */
  772       public JCMethodDecl MethodDef(MethodSymbol m, JCBlock body) {
  773           return MethodDef(m, m.type, body);
  774       }
  775   
  776       /** Create a method definition from a method symbol, method type
  777        *  and a method body.
  778        */
  779       public JCMethodDecl MethodDef(MethodSymbol m, Type mtype, JCBlock body) {
  780           return (JCMethodDecl)
  781               new JCMethodDecl(
  782                   Modifiers(m.flags(), Annotations(m.getAnnotationMirrors())),
  783                   m.name,
  784                   Type(mtype.getReturnType()),
  785                   TypeParams(mtype.getTypeArguments()),
  786                   Params(mtype.getParameterTypes(), m),
  787                   Types(mtype.getThrownTypes()),
  788                   body,
  789                   null,
  790                   m).setPos(pos).setType(mtype);
  791       }
  792   
  793       /** Create a type parameter tree from its name and type.
  794        */
  795       public JCTypeParameter TypeParam(Name name, TypeVar tvar) {
  796           return (JCTypeParameter)
  797               TypeParameter(name, Types(types.getBounds(tvar))).setPos(pos).setType(tvar);
  798       }
  799   
  800       /** Create a list of type parameter trees from a list of type variables.
  801        */
  802       public List<JCTypeParameter> TypeParams(List<Type> typarams) {
  803           ListBuffer<JCTypeParameter> tparams = new ListBuffer<JCTypeParameter>();
  804           int i = 0;
  805           for (List<Type> l = typarams; l.nonEmpty(); l = l.tail)
  806               tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head));
  807           return tparams.toList();
  808       }
  809   
  810       /** Create a value parameter tree from its name, type, and owner.
  811        */
  812       public JCVariableDecl Param(Name name, Type argtype, Symbol owner) {
  813           return VarDef(new VarSymbol(0, name, argtype, owner), null);
  814       }
  815   
  816       /** Create a a list of value parameter trees x0, ..., xn from a list of
  817        *  their types and an their owner.
  818        */
  819       public List<JCVariableDecl> Params(List<Type> argtypes, Symbol owner) {
  820           ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
  821           MethodSymbol mth = (owner.kind == MTH) ? ((MethodSymbol)owner) : null;
  822           if (mth != null && mth.params != null && argtypes.length() == mth.params.length()) {
  823               for (VarSymbol param : ((MethodSymbol)owner).params)
  824                   params.append(VarDef(param, null));
  825           } else {
  826               int i = 0;
  827               for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
  828                   params.append(Param(paramName(i++), l.head, owner));
  829           }
  830           return params.toList();
  831       }
  832   
  833       /** Wrap a method invocation in an expression statement or return statement,
  834        *  depending on whether the method invocation expression's type is void.
  835        */
  836       public JCStatement Call(JCExpression apply) {
  837           return apply.type.tag == VOID ? Exec(apply) : Return(apply);
  838       }
  839   
  840       /** Construct an assignment from a variable symbol and a right hand side.
  841        */
  842       public JCStatement Assignment(Symbol v, JCExpression rhs) {
  843           return Exec(Assign(Ident(v), rhs).setType(v.type));
  844       }
  845   
  846       /** Construct an index expression from a variable and an expression.
  847        */
  848       public JCArrayAccess Indexed(Symbol v, JCExpression index) {
  849           JCArrayAccess tree = new JCArrayAccess(QualIdent(v), index);
  850           tree.type = ((ArrayType)v.type).elemtype;
  851           return tree;
  852       }
  853   
  854       /** Make an attributed type cast expression.
  855        */
  856       public JCTypeCast TypeCast(Type type, JCExpression expr) {
  857           return (JCTypeCast)TypeCast(Type(type), expr).setType(type);
  858       }
  859   
  860   /* ***************************************************************************
  861    * Helper methods.
  862    ****************************************************************************/
  863   
  864       /** Can given symbol be referred to in unqualified form?
  865        */
  866       boolean isUnqualifiable(Symbol sym) {
  867           if (sym.name == names.empty ||
  868               sym.owner == null ||
  869               sym.owner.kind == MTH || sym.owner.kind == VAR) {
  870               return true;
  871           } else if (sym.kind == TYP && toplevel != null) {
  872               Scope.Entry e;
  873               e = toplevel.namedImportScope.lookup(sym.name);
  874               if (e.scope != null) {
  875                   return
  876                     e.sym == sym &&
  877                     e.next().scope == null;
  878               }
  879               e = toplevel.packge.members().lookup(sym.name);
  880               if (e.scope != null) {
  881                   return
  882                     e.sym == sym &&
  883                     e.next().scope == null;
  884               }
  885               e = toplevel.starImportScope.lookup(sym.name);
  886               if (e.scope != null) {
  887                   return
  888                     e.sym == sym &&
  889                     e.next().scope == null;
  890               }
  891           }
  892           return false;
  893       }
  894   
  895       /** The name of synthetic parameter number `i'.
  896        */
  897       public Name paramName(int i)   { return names.fromString("x" + i); }
  898   
  899       /** The name of synthetic type parameter number `i'.
  900        */
  901       public Name typaramName(int i) { return names.fromString("A" + i); }
  902   }

Home » openjdk-7 » com.sun.tools » javac » tree » [javadoc | source]