41 * A combined type/symbol visitor for generating non-trivial localized string |
41 * A combined type/symbol visitor for generating non-trivial localized string |
42 * representation of types and symbols. |
42 * representation of types and symbols. |
43 */ |
43 */ |
44 public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Visitor<String, Locale> { |
44 public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Visitor<String, Locale> { |
45 |
45 |
|
46 List<Type> seenCaptured = List.nil(); |
|
47 static final int PRIME = 997; // largest prime less than 1000 |
|
48 |
46 /** |
49 /** |
47 * This method should be overriden in order to provide proper i18n support. |
50 * This method should be overriden in order to provide proper i18n support. |
48 * |
51 * |
49 * @param locale the locale in which the string is to be rendered |
52 * @param locale the locale in which the string is to be rendered |
50 * @param key the key corresponding to the message to be displayed |
53 * @param key the key corresponding to the message to be displayed |
52 * @return localized string representation |
55 * @return localized string representation |
53 */ |
56 */ |
54 protected abstract String localize(Locale locale, String key, Object... args); |
57 protected abstract String localize(Locale locale, String key, Object... args); |
55 |
58 |
56 /** |
59 /** |
57 * Create a printer with default i18n support provided my Messages. |
60 * Maps a captured type into an unique identifier. |
|
61 * |
|
62 * @param t the captured type for which an id is to be retrieved |
|
63 * @param locale locale settings |
|
64 * @return unique id representing this captured type |
|
65 */ |
|
66 protected abstract String capturedVarId(CapturedType t, Locale locale); |
|
67 |
|
68 /** |
|
69 * Create a printer with default i18n support provided by Messages. By default, |
|
70 * captured types ids are generated using hashcode. |
|
71 * |
58 * @param messages Messages class to be used for i18n |
72 * @param messages Messages class to be used for i18n |
59 * @return printer visitor instance |
73 * @return printer visitor instance |
60 */ |
74 */ |
61 public static Printer createStandardPrinter(final Messages messages) { |
75 public static Printer createStandardPrinter(final Messages messages) { |
62 return new Printer() { |
76 return new Printer() { |
63 @Override |
77 @Override |
64 protected String localize(Locale locale, String key, Object... args) { |
78 protected String localize(Locale locale, String key, Object... args) { |
65 return messages.getLocalizedString(locale, key, args); |
79 return messages.getLocalizedString(locale, key, args); |
|
80 } |
|
81 |
|
82 @Override |
|
83 protected String capturedVarId(CapturedType t, Locale locale) { |
|
84 return (t.hashCode() & 0xFFFFFFFFL) % PRIME + ""; |
66 }}; |
85 }}; |
67 } |
86 } |
68 |
87 |
69 /** |
88 /** |
70 * Get a localized string representation for all the types in the input list. |
89 * Get a localized string representation for all the types in the input list. |
118 return s.accept(this, locale); |
137 return s.accept(this, locale); |
119 } |
138 } |
120 |
139 |
121 @Override |
140 @Override |
122 public String visitCapturedType(CapturedType t, Locale locale) { |
141 public String visitCapturedType(CapturedType t, Locale locale) { |
123 return localize(locale, "compiler.misc.type.captureof", |
142 if (seenCaptured.contains(t)) |
124 (t.hashCode() & 0xFFFFFFFFL) % Type.CapturedType.PRIME, |
143 return localize(locale, "compiler.misc.type.captureof.1", |
125 visit(t.wildcard, locale)); |
144 capturedVarId(t, locale)); |
|
145 else { |
|
146 try { |
|
147 seenCaptured = seenCaptured.prepend(t); |
|
148 return localize(locale, "compiler.misc.type.captureof", |
|
149 capturedVarId(t, locale), |
|
150 visit(t.wildcard, locale)); |
|
151 } |
|
152 finally { |
|
153 seenCaptured = seenCaptured.tail; |
|
154 } |
|
155 } |
126 } |
156 } |
127 |
157 |
128 @Override |
158 @Override |
129 public String visitForAll(ForAll t, Locale locale) { |
159 public String visitForAll(ForAll t, Locale locale) { |
130 return "<" + visitTypes(t.tvars, locale) + ">" + visit(t.qtype, locale); |
160 return "<" + visitTypes(t.tvars, locale) + ">" + visit(t.qtype, locale); |