Save This Page
Home » openjdk-7 » com.sun.tools » javac » code » [javadoc | source]
    1   /*
    2    * Copyright (c) 2009, 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.code;
   27   
   28   import java.util.Locale;
   29   
   30   import com.sun.tools.javac.api.Messages;
   31   import com.sun.tools.javac.code.Type;
   32   import com.sun.tools.javac.code.Symbol;
   33   import com.sun.tools.javac.util.List;
   34   import com.sun.tools.javac.util.ListBuffer;
   35   
   36   import static com.sun.tools.javac.code.TypeTags.*;
   37   import static com.sun.tools.javac.code.BoundKind.*;
   38   import static com.sun.tools.javac.code.Flags.*;
   39   
   40   /**
   41    * A combined type/symbol visitor for generating non-trivial localized string
   42    * representation of types and symbols.
   43    *
   44    * <p><b>This is NOT part of any supported API.
   45    * If you write code that depends on this, you do so at your own risk.
   46    * This code and its internal interfaces are subject to change or
   47    * deletion without notice.</b>
   48    */
   49   public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Visitor<String, Locale> {
   50   
   51       List<Type> seenCaptured = List.nil();
   52       static final int PRIME = 997;  // largest prime less than 1000
   53   
   54       /**
   55        * This method should be overriden in order to provide proper i18n support.
   56        *
   57        * @param locale the locale in which the string is to be rendered
   58        * @param key the key corresponding to the message to be displayed
   59        * @param args a list of optional arguments
   60        * @return localized string representation
   61        */
   62       protected abstract String localize(Locale locale, String key, Object... args);
   63   
   64       /**
   65        * Maps a captured type into an unique identifier.
   66        *
   67        * @param t the captured type for which an id is to be retrieved
   68        * @param locale locale settings
   69        * @return unique id representing this captured type
   70        */
   71       protected abstract String capturedVarId(CapturedType t, Locale locale);
   72   
   73       /**
   74        * Create a printer with default i18n support provided by Messages. By default,
   75        * captured types ids are generated using hashcode.
   76        *
   77        * @param messages Messages class to be used for i18n
   78        * @return printer visitor instance
   79        */
   80       public static Printer createStandardPrinter(final Messages messages) {
   81           return new Printer() {
   82               @Override
   83               protected String localize(Locale locale, String key, Object... args) {
   84                   return messages.getLocalizedString(locale, key, args);
   85               }
   86   
   87               @Override
   88               protected String capturedVarId(CapturedType t, Locale locale) {
   89                   return (t.hashCode() & 0xFFFFFFFFL) % PRIME + "";
   90           }};
   91       }
   92   
   93       /**
   94        * Get a localized string representation for all the types in the input list.
   95        *
   96        * @param ts types to be displayed
   97        * @param locale the locale in which the string is to be rendered
   98        * @return localized string representation
   99        */
  100       public String visitTypes(List<Type> ts, Locale locale) {
  101           ListBuffer<String> sbuf = ListBuffer.lb();
  102           for (Type t : ts) {
  103               sbuf.append(visit(t, locale));
  104           }
  105           return sbuf.toList().toString();
  106       }
  107   
  108       /**
  109        * * Get a localized string representation for all the symbols in the input list.
  110        *
  111        * @param ts symbols to be displayed
  112        * @param locale the locale in which the string is to be rendered
  113        * @return localized string representation
  114        */
  115       public String visitSymbols(List<Symbol> ts, Locale locale) {
  116           ListBuffer<String> sbuf = ListBuffer.lb();
  117           for (Symbol t : ts) {
  118               sbuf.append(visit(t, locale));
  119           }
  120           return sbuf.toList().toString();
  121       }
  122   
  123       /**
  124        * Get a localized string represenation for a given type.
  125        *
  126        * @param ts type to be displayed
  127        * @param locale the locale in which the string is to be rendered
  128        * @return localized string representation
  129        */
  130       public String visit(Type t, Locale locale) {
  131           return t.accept(this, locale);
  132       }
  133   
  134       /**
  135        * Get a localized string represenation for a given symbol.
  136        *
  137        * @param ts symbol to be displayed
  138        * @param locale the locale in which the string is to be rendered
  139        * @return localized string representation
  140        */
  141       public String visit(Symbol s, Locale locale) {
  142           return s.accept(this, locale);
  143       }
  144   
  145       @Override
  146       public String visitCapturedType(CapturedType t, Locale locale) {
  147           if (seenCaptured.contains(t))
  148               return localize(locale, "compiler.misc.type.captureof.1",
  149                   capturedVarId(t, locale));
  150           else {
  151               try {
  152                   seenCaptured = seenCaptured.prepend(t);
  153                   return localize(locale, "compiler.misc.type.captureof",
  154                       capturedVarId(t, locale),
  155                       visit(t.wildcard, locale));
  156               }
  157               finally {
  158                   seenCaptured = seenCaptured.tail;
  159               }
  160           }
  161       }
  162   
  163       @Override
  164       public String visitForAll(ForAll t, Locale locale) {
  165           return "<" + visitTypes(t.tvars, locale) + ">" + visit(t.qtype, locale);
  166       }
  167   
  168       @Override
  169       public String visitUndetVar(UndetVar t, Locale locale) {
  170           if (t.inst != null) {
  171               return visit(t.inst, locale);
  172           } else {
  173               return visit(t.qtype, locale) + "?";
  174           }
  175       }
  176   
  177       @Override
  178       public String visitArrayType(ArrayType t, Locale locale) {
  179           return visit(t.elemtype, locale) + "[]";
  180       }
  181   
  182       @Override
  183       public String visitClassType(ClassType t, Locale locale) {
  184           StringBuffer buf = new StringBuffer();
  185           if (t.getEnclosingType().tag == CLASS && t.tsym.owner.kind == Kinds.TYP) {
  186               buf.append(visit(t.getEnclosingType(), locale));
  187               buf.append(".");
  188               buf.append(className(t, false, locale));
  189           } else {
  190               buf.append(className(t, true, locale));
  191           }
  192           if (t.getTypeArguments().nonEmpty()) {
  193               buf.append('<');
  194               buf.append(visitTypes(t.getTypeArguments(), locale));
  195               buf.append(">");
  196           }
  197           return buf.toString();
  198       }
  199   
  200       @Override
  201       public String visitMethodType(MethodType t, Locale locale) {
  202           return "(" + printMethodArgs(t.argtypes, false, locale) + ")" + visit(t.restype, locale);
  203       }
  204   
  205       @Override
  206       public String visitPackageType(PackageType t, Locale locale) {
  207           return t.tsym.getQualifiedName().toString();
  208       }
  209   
  210       @Override
  211       public String visitWildcardType(WildcardType t, Locale locale) {
  212           StringBuffer s = new StringBuffer();
  213           s.append(t.kind);
  214           if (t.kind != UNBOUND) {
  215               s.append(visit(t.type, locale));
  216           }
  217           return s.toString();
  218       }
  219   
  220       @Override
  221       public String visitErrorType(ErrorType t, Locale locale) {
  222           return visitType(t, locale);
  223       }
  224   
  225       @Override
  226       public String visitTypeVar(TypeVar t, Locale locale) {
  227           return visitType(t, locale);
  228       }
  229   
  230       public String visitType(Type t, Locale locale) {
  231           String s = (t.tsym == null || t.tsym.name == null)
  232                   ? localize(locale, "compiler.misc.type.none")
  233                   : t.tsym.name.toString();
  234           return s;
  235       }
  236   
  237       /**
  238        * Converts a class name into a (possibly localized) string. Anonymous
  239        * inner classes gets converted into a localized string.
  240        *
  241        * @param t the type of the class whose name is to be rendered
  242        * @param longform if set, the class' fullname is displayed - if unset the
  243        * short name is chosen (w/o package)
  244        * @param locale the locale in which the string is to be rendered
  245        * @return localized string representation
  246        */
  247       protected String className(ClassType t, boolean longform, Locale locale) {
  248           Symbol sym = t.tsym;
  249           if (sym.name.length() == 0 && (sym.flags() & COMPOUND) != 0) {
  250               StringBuffer s = new StringBuffer(visit(t.supertype_field, locale));
  251               for (List<Type> is = t.interfaces_field; is.nonEmpty(); is = is.tail) {
  252                   s.append("&");
  253                   s.append(visit(is.head, locale));
  254               }
  255               return s.toString();
  256           } else if (sym.name.length() == 0) {
  257               String s;
  258               ClassType norm = (ClassType) t.tsym.type;
  259               if (norm == null) {
  260                   s = localize(locale, "compiler.misc.anonymous.class", (Object) null);
  261               } else if (norm.interfaces_field.nonEmpty()) {
  262                   s = localize(locale, "compiler.misc.anonymous.class",
  263                           visit(norm.interfaces_field.head, locale));
  264               } else {
  265                   s = localize(locale, "compiler.misc.anonymous.class",
  266                           visit(norm.supertype_field, locale));
  267               }
  268               return s;
  269           } else if (longform) {
  270               return sym.getQualifiedName().toString();
  271           } else {
  272               return sym.name.toString();
  273           }
  274       }
  275   
  276       /**
  277        * Converts a set of method argument types into their corresponding
  278        * localized string representation.
  279        *
  280        * @param args arguments to be rendered
  281        * @param varArgs if true, the last method argument is regarded as a vararg
  282        * @param locale the locale in which the string is to be rendered
  283        * @return localized string representation
  284        */
  285       protected String printMethodArgs(List<Type> args, boolean varArgs, Locale locale) {
  286           if (!varArgs) {
  287               return visitTypes(args, locale);
  288           } else {
  289               StringBuffer buf = new StringBuffer();
  290               while (args.tail.nonEmpty()) {
  291                   buf.append(visit(args.head, locale));
  292                   args = args.tail;
  293                   buf.append(',');
  294               }
  295               if (args.head.tag == ARRAY) {
  296                   buf.append(visit(((ArrayType) args.head).elemtype, locale));
  297                   buf.append("...");
  298               } else {
  299                   buf.append(visit(args.head, locale));
  300               }
  301               return buf.toString();
  302           }
  303       }
  304   
  305       @Override
  306       public String visitClassSymbol(ClassSymbol sym, Locale locale) {
  307           return sym.name.isEmpty()
  308                   ? localize(locale, "compiler.misc.anonymous.class", sym.flatname)
  309                   : sym.fullname.toString();
  310       }
  311   
  312       @Override
  313       public String visitMethodSymbol(MethodSymbol s, Locale locale) {
  314           if ((s.flags() & BLOCK) != 0) {
  315               return s.owner.name.toString();
  316           } else {
  317               String ms = (s.name == s.name.table.names.init)
  318                       ? s.owner.name.toString()
  319                       : s.name.toString();
  320               if (s.type != null) {
  321                   if (s.type.tag == FORALL) {
  322                       ms = "<" + visitTypes(s.type.getTypeArguments(), locale) + ">" + ms;
  323                   }
  324                   ms += "(" + printMethodArgs(
  325                           s.type.getParameterTypes(),
  326                           (s.flags() & VARARGS) != 0,
  327                           locale) + ")";
  328               }
  329               return ms;
  330           }
  331       }
  332   
  333       @Override
  334       public String visitOperatorSymbol(OperatorSymbol s, Locale locale) {
  335           return visitMethodSymbol(s, locale);
  336       }
  337   
  338       @Override
  339       public String visitPackageSymbol(PackageSymbol s, Locale locale) {
  340           return s.isUnnamed()
  341                   ? localize(locale, "compiler.misc.unnamed.package")
  342                   : s.fullname.toString();
  343       }
  344   
  345       @Override
  346       public String visitTypeSymbol(TypeSymbol s, Locale locale) {
  347           return visitSymbol(s, locale);
  348       }
  349   
  350       @Override
  351       public String visitVarSymbol(VarSymbol s, Locale locale) {
  352           return visitSymbol(s, locale);
  353       }
  354   
  355       @Override
  356       public String visitSymbol(Symbol s, Locale locale) {
  357           return s.name.toString();
  358       }
  359   }

Save This Page
Home » openjdk-7 » com.sun.tools » javac » code » [javadoc | source]