1.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java Mon Sep 29 11:34:43 2008 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Mon Sep 29 11:48:09 2008 +0100 1.3 @@ -67,6 +67,7 @@ 1.4 new Context.Key<Types>(); 1.5 1.6 final Symtab syms; 1.7 + final Messages messages; 1.8 final Names names; 1.9 final boolean allowBoxing; 1.10 final ClassReader reader; 1.11 @@ -92,6 +93,7 @@ 1.12 source = Source.instance(context); 1.13 chk = Check.instance(context); 1.14 capturedName = names.fromString("<captured wildcard>"); 1.15 + messages = Messages.instance(context); 1.16 } 1.17 // </editor-fold> 1.18 1.19 @@ -1589,10 +1591,10 @@ 1.20 syms.noSymbol); 1.21 if (bounds.head.tag == TYPEVAR) 1.22 // error condition, recover 1.23 - bc.erasure_field = syms.objectType; 1.24 - else 1.25 - bc.erasure_field = erasure(bounds.head); 1.26 - bc.members_field = new Scope(bc); 1.27 + bc.erasure_field = syms.objectType; 1.28 + else 1.29 + bc.erasure_field = erasure(bounds.head); 1.30 + bc.members_field = new Scope(bc); 1.31 ClassType bt = (ClassType)bc.type; 1.32 bt.allparams_field = List.nil(); 1.33 if (supertype != null) { 1.34 @@ -2249,10 +2251,234 @@ 1.35 } 1.36 // </editor-fold> 1.37 1.38 + // <editor-fold defaultstate="collapsed" desc="printType"> 1.39 + /** 1.40 + * Visitor for generating a string representation of a given type 1.41 + * accordingly to a given locale 1.42 + */ 1.43 + public String toString(Type t, Locale locale) { 1.44 + return typePrinter.visit(t, locale); 1.45 + } 1.46 + // where 1.47 + private TypePrinter typePrinter = new TypePrinter(); 1.48 + 1.49 + public class TypePrinter extends DefaultTypeVisitor<String, Locale> { 1.50 + 1.51 + public String visit(List<Type> ts, Locale locale) { 1.52 + ListBuffer<String> sbuf = lb(); 1.53 + for (Type t : ts) { 1.54 + sbuf.append(visit(t, locale)); 1.55 + } 1.56 + return sbuf.toList().toString(); 1.57 + } 1.58 + 1.59 + @Override 1.60 + public String visitCapturedType(CapturedType t, Locale locale) { 1.61 + return messages.getLocalizedString("compiler.misc.type.captureof", 1.62 + (t.hashCode() & 0xFFFFFFFFL) % Type.CapturedType.PRIME, 1.63 + visit(t.wildcard, locale)); 1.64 + } 1.65 + 1.66 + @Override 1.67 + public String visitForAll(ForAll t, Locale locale) { 1.68 + return "<" + visit(t.tvars, locale) + ">" + visit(t.qtype, locale); 1.69 + } 1.70 + 1.71 + @Override 1.72 + public String visitUndetVar(UndetVar t, Locale locale) { 1.73 + if (t.inst != null) { 1.74 + return visit(t.inst, locale); 1.75 + } else { 1.76 + return visit(t.qtype, locale) + "?"; 1.77 + } 1.78 + } 1.79 + 1.80 + @Override 1.81 + public String visitArrayType(ArrayType t, Locale locale) { 1.82 + return visit(t.elemtype, locale) + "[]"; 1.83 + } 1.84 + 1.85 + @Override 1.86 + public String visitClassType(ClassType t, Locale locale) { 1.87 + StringBuffer buf = new StringBuffer(); 1.88 + if (t.getEnclosingType().tag == CLASS && t.tsym.owner.kind == Kinds.TYP) { 1.89 + buf.append(visit(t.getEnclosingType(), locale)); 1.90 + buf.append("."); 1.91 + buf.append(className(t, false, locale)); 1.92 + } else { 1.93 + buf.append(className(t, true, locale)); 1.94 + } 1.95 + if (t.getTypeArguments().nonEmpty()) { 1.96 + buf.append('<'); 1.97 + buf.append(visit(t.getTypeArguments(), locale)); 1.98 + buf.append(">"); 1.99 + } 1.100 + return buf.toString(); 1.101 + } 1.102 + 1.103 + @Override 1.104 + public String visitMethodType(MethodType t, Locale locale) { 1.105 + return "(" + printMethodArgs(t.argtypes, false, locale) + ")" + visit(t.restype, locale); 1.106 + } 1.107 + 1.108 + @Override 1.109 + public String visitPackageType(PackageType t, Locale locale) { 1.110 + return t.tsym.getQualifiedName().toString(); 1.111 + } 1.112 + 1.113 + @Override 1.114 + public String visitWildcardType(WildcardType t, Locale locale) { 1.115 + StringBuffer s = new StringBuffer(); 1.116 + s.append(t.kind); 1.117 + if (t.kind != UNBOUND) { 1.118 + s.append(visit(t.type, locale)); 1.119 + } 1.120 + return s.toString(); 1.121 + } 1.122 + 1.123 + 1.124 + public String visitType(Type t, Locale locale) { 1.125 + String s = (t.tsym == null || t.tsym.name == null) 1.126 + ? messages.getLocalizedString("compiler.misc.type.none") 1.127 + : t.tsym.name.toString(); 1.128 + return s; 1.129 + } 1.130 + 1.131 + protected String className(ClassType t, boolean longform, Locale locale) { 1.132 + Symbol sym = t.tsym; 1.133 + if (sym.name.length() == 0 && (sym.flags() & COMPOUND) != 0) { 1.134 + StringBuffer s = new StringBuffer(visit(supertype(t), locale)); 1.135 + for (List<Type> is = interfaces(t); is.nonEmpty(); is = is.tail) { 1.136 + s.append("&"); 1.137 + s.append(visit(is.head, locale)); 1.138 + } 1.139 + return s.toString(); 1.140 + } else if (sym.name.length() == 0) { 1.141 + String s; 1.142 + ClassType norm = (ClassType) t.tsym.type; 1.143 + if (norm == null) { 1.144 + s = getLocalizedString(locale, "compiler.misc.anonymous.class", (Object) null); 1.145 + } else if (interfaces(norm).nonEmpty()) { 1.146 + s = getLocalizedString(locale, "compiler.misc.anonymous.class", 1.147 + visit(interfaces(norm).head, locale)); 1.148 + } else { 1.149 + s = getLocalizedString(locale, "compiler.misc.anonymous.class", 1.150 + visit(supertype(norm), locale)); 1.151 + } 1.152 + return s; 1.153 + } else if (longform) { 1.154 + return sym.getQualifiedName().toString(); 1.155 + } else { 1.156 + return sym.name.toString(); 1.157 + } 1.158 + } 1.159 + 1.160 + protected String printMethodArgs(List<Type> args, boolean varArgs, Locale locale) { 1.161 + if (!varArgs) { 1.162 + return visit(args, locale); 1.163 + } else { 1.164 + StringBuffer buf = new StringBuffer(); 1.165 + while (args.tail.nonEmpty()) { 1.166 + buf.append(visit(args.head, locale)); 1.167 + args = args.tail; 1.168 + buf.append(','); 1.169 + } 1.170 + if (args.head.tag == ARRAY) { 1.171 + buf.append(visit(((ArrayType) args.head).elemtype, locale)); 1.172 + buf.append("..."); 1.173 + } else { 1.174 + buf.append(visit(args.head, locale)); 1.175 + } 1.176 + return buf.toString(); 1.177 + } 1.178 + } 1.179 + 1.180 + protected String getLocalizedString(Locale locale, String key, Object... args) { 1.181 + return messages.getLocalizedString(key, args); 1.182 + } 1.183 + }; 1.184 + // </editor-fold> 1.185 + 1.186 + // <editor-fold defaultstate="collapsed" desc="printSymbol"> 1.187 + /** 1.188 + * Visitor for generating a string representation of a given symbol 1.189 + * accordingly to a given locale 1.190 + */ 1.191 + public String toString(Symbol t, Locale locale) { 1.192 + return symbolPrinter.visit(t, locale); 1.193 + } 1.194 + // where 1.195 + private SymbolPrinter symbolPrinter = new SymbolPrinter(); 1.196 + 1.197 + public class SymbolPrinter extends DefaultSymbolVisitor<String, Locale> { 1.198 + 1.199 + @Override 1.200 + public String visitClassSymbol(ClassSymbol sym, Locale locale) { 1.201 + return sym.name.isEmpty() 1.202 + ? getLocalizedString(locale, "compiler.misc.anonymous.class", sym.flatname) 1.203 + : sym.fullname.toString(); 1.204 + } 1.205 + 1.206 + @Override 1.207 + public String visitMethodSymbol(MethodSymbol s, Locale locale) { 1.208 + if ((s.flags() & BLOCK) != 0) { 1.209 + return s.owner.name.toString(); 1.210 + } else { 1.211 + String ms = (s.name == names.init) 1.212 + ? s.owner.name.toString() 1.213 + : s.name.toString(); 1.214 + if (s.type != null) { 1.215 + if (s.type.tag == FORALL) { 1.216 + ms = "<" + typePrinter.visit(s.type.getTypeArguments(), locale) + ">" + ms; 1.217 + } 1.218 + ms += "(" + typePrinter.printMethodArgs( 1.219 + s.type.getParameterTypes(), 1.220 + (s.flags() & VARARGS) != 0, 1.221 + locale) + ")"; 1.222 + } 1.223 + return ms; 1.224 + } 1.225 + } 1.226 + 1.227 + @Override 1.228 + public String visitOperatorSymbol(OperatorSymbol s, Locale locale) { 1.229 + return visitMethodSymbol(s, locale); 1.230 + } 1.231 + 1.232 + @Override 1.233 + public String visitPackageSymbol(PackageSymbol s, Locale locale) { 1.234 + return s.name.isEmpty() 1.235 + ? getLocalizedString(locale, "compiler.misc.unnamed.package") 1.236 + : s.fullname.toString(); 1.237 + } 1.238 + 1.239 + @Override 1.240 + public String visitSymbol(Symbol s, Locale locale) { 1.241 + return s.name.toString(); 1.242 + } 1.243 + 1.244 + public String visit(List<Symbol> ts, Locale locale) { 1.245 + ListBuffer<String> sbuf = lb(); 1.246 + for (Symbol t : ts) { 1.247 + sbuf.append(visit(t, locale)); 1.248 + } 1.249 + return sbuf.toList().toString(); 1.250 + } 1.251 + 1.252 + protected String getLocalizedString(Locale locale, String key, Object... args) { 1.253 + return messages.getLocalizedString(key, args); 1.254 + } 1.255 + }; 1.256 + // </editor-fold> 1.257 + 1.258 // <editor-fold defaultstate="collapsed" desc="toString"> 1.259 /** 1.260 * This toString is slightly more descriptive than the one on Type. 1.261 + * 1.262 + * @deprecated Types.toString(Type t, Locale l) provides better support 1.263 + * for localization 1.264 */ 1.265 + @Deprecated 1.266 public String toString(Type t) { 1.267 if (t.tag == FORALL) { 1.268 ForAll forAll = (ForAll)t; 1.269 @@ -3236,6 +3462,28 @@ 1.270 } 1.271 1.272 /** 1.273 + * A default visitor for symbols. All visitor methods except 1.274 + * visitSymbol are implemented by delegating to visitSymbol. Concrete 1.275 + * subclasses must provide an implementation of visitSymbol and can 1.276 + * override other methods as needed. 1.277 + * 1.278 + * @param <R> the return type of the operation implemented by this 1.279 + * visitor; use Void if no return type is needed. 1.280 + * @param <S> the type of the second argument (the first being the 1.281 + * symbol itself) of the operation implemented by this visitor; use 1.282 + * Void if a second argument is not needed. 1.283 + */ 1.284 + public static abstract class DefaultSymbolVisitor<R,S> implements Symbol.Visitor<R,S> { 1.285 + final public R visit(Symbol s, S arg) { return s.accept(this, arg); } 1.286 + public R visitClassSymbol(ClassSymbol s, S arg) { return visitSymbol(s, arg); } 1.287 + public R visitMethodSymbol(MethodSymbol s, S arg) { return visitSymbol(s, arg); } 1.288 + public R visitOperatorSymbol(OperatorSymbol s, S arg) { return visitSymbol(s, arg); } 1.289 + public R visitPackageSymbol(PackageSymbol s, S arg) { return visitSymbol(s, arg); } 1.290 + public R visitTypeSymbol(TypeSymbol s, S arg) { return visitSymbol(s, arg); } 1.291 + public R visitVarSymbol(VarSymbol s, S arg) { return visitSymbol(s, arg); } 1.292 + } 1.293 + 1.294 + /** 1.295 * A <em>simple</em> visitor for types. This visitor is simple as 1.296 * captured wildcards, for-all types (generic methods), and 1.297 * undetermined type variables (part of inference) are hidden.