src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java

Fri, 30 Nov 2012 15:14:48 +0000

author
mcimadamore
date
Fri, 30 Nov 2012 15:14:48 +0000
changeset 1436
f6f1fd261f57
parent 1413
bdcef2ef52d2
child 1569
475eb15dfdad
permissions
-rw-r--r--

8002099: Add support for intersection types in cast expression
Summary: Add parser and type-checking support for intersection types in cast expressions
Reviewed-by: jjg

mcimadamore@83 1 /*
jjg@1358 2 * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
mcimadamore@83 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
mcimadamore@83 4 *
mcimadamore@83 5 * This code is free software; you can redistribute it and/or modify it
mcimadamore@83 6 * under the terms of the GNU General Public License version 2 only, as
ohair@554 7 * published by the Free Software Foundation. Oracle designates this
mcimadamore@83 8 * particular file as subject to the "Classpath" exception as provided
ohair@554 9 * by Oracle in the LICENSE file that accompanied this code.
mcimadamore@83 10 *
mcimadamore@83 11 * This code is distributed in the hope that it will be useful, but WITHOUT
mcimadamore@83 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
mcimadamore@83 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mcimadamore@83 14 * version 2 for more details (a copy is included in the LICENSE file that
mcimadamore@83 15 * accompanied this code).
mcimadamore@83 16 *
mcimadamore@83 17 * You should have received a copy of the GNU General Public License version
mcimadamore@83 18 * 2 along with this work; if not, write to the Free Software Foundation,
mcimadamore@83 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
mcimadamore@83 20 *
ohair@554 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@554 22 * or visit www.oracle.com if you need additional information or have any
ohair@554 23 * questions.
mcimadamore@83 24 */
mcimadamore@83 25 package com.sun.tools.javac.util;
mcimadamore@83 26
mcimadamore@221 27 import java.util.Arrays;
mcimadamore@83 28 import java.util.Collection;
mcimadamore@221 29 import java.util.EnumSet;
mcimadamore@221 30 import java.util.HashMap;
mcimadamore@83 31 import java.util.Locale;
mcimadamore@221 32 import java.util.Map;
mcimadamore@221 33 import java.util.Set;
jjg@1413 34
mcimadamore@83 35 import javax.tools.JavaFileObject;
mcimadamore@83 36
mcimadamore@83 37 import com.sun.tools.javac.api.DiagnosticFormatter;
mcimadamore@221 38 import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart;
mcimadamore@221 39 import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.MultilineLimit;
mcimadamore@221 40 import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
mcimadamore@83 41 import com.sun.tools.javac.api.Formattable;
jjg@612 42 import com.sun.tools.javac.code.Lint.LintCategory;
mcimadamore@238 43 import com.sun.tools.javac.code.Printer;
mcimadamore@238 44 import com.sun.tools.javac.code.Symbol;
mcimadamore@238 45 import com.sun.tools.javac.code.Type;
mcimadamore@238 46 import com.sun.tools.javac.code.Type.CapturedType;
jjg@1413 47 import com.sun.tools.javac.file.BaseFileObject;
mcimadamore@1348 48 import com.sun.tools.javac.tree.JCTree.*;
mcimadamore@1348 49 import com.sun.tools.javac.tree.Pretty;
mcimadamore@137 50 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
mcimadamore@83 51
mcimadamore@83 52 /**
mcimadamore@83 53 * This abstract class provides a basic implementation of the functionalities that should be provided
mcimadamore@83 54 * by any formatter used by javac. Among the main features provided by AbstractDiagnosticFormatter are:
mcimadamore@83 55 *
mcimadamore@83 56 * <ul>
mcimadamore@83 57 * <li> Provides a standard implementation of the visitor-like methods defined in the interface DiagnisticFormatter.
mcimadamore@83 58 * Those implementations are specifically targeting JCDiagnostic objects.
mcimadamore@83 59 * <li> Provides basic support for i18n and a method for executing all locale-dependent conversions
mcimadamore@83 60 * <li> Provides the formatting logic for rendering the arguments of a JCDiagnostic object.
mcimadamore@83 61 * <ul>
mcimadamore@83 62 *
jjg@581 63 * <p><b>This is NOT part of any supported API.
jjg@333 64 * If you write code that depends on this, you do so at your own risk.
jjg@333 65 * This code and its internal interfaces are subject to change or
jjg@333 66 * deletion without notice.</b>
mcimadamore@83 67 */
mcimadamore@83 68 public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter<JCDiagnostic> {
mcimadamore@83 69
mcimadamore@83 70 /**
mcimadamore@221 71 * JavacMessages object used by this formatter for i18n.
mcimadamore@83 72 */
mcimadamore@136 73 protected JavacMessages messages;
mcimadamore@238 74
mcimadamore@238 75 /**
mcimadamore@238 76 * Configuration object used by this formatter
mcimadamore@238 77 */
mcimadamore@221 78 private SimpleConfiguration config;
mcimadamore@238 79
mcimadamore@238 80 /**
mcimadamore@238 81 * Current depth level of the disgnostic being formatted
mcimadamore@238 82 * (!= 0 for subdiagnostics)
mcimadamore@238 83 */
mcimadamore@221 84 protected int depth = 0;
mcimadamore@83 85
mcimadamore@83 86 /**
mcimadamore@288 87 * All captured types that have been encountered during diagnostic formatting.
mcimadamore@288 88 * This info is used by the FormatterPrinter in order to print friendly unique
mcimadamore@288 89 * ids for captured types
mcimadamore@238 90 */
mcimadamore@288 91 private List<Type> allCaptured = List.nil();
mcimadamore@238 92
mcimadamore@238 93 /**
mcimadamore@221 94 * Initialize an AbstractDiagnosticFormatter by setting its JavacMessages object.
mcimadamore@83 95 * @param messages
mcimadamore@83 96 */
mcimadamore@221 97 protected AbstractDiagnosticFormatter(JavacMessages messages, SimpleConfiguration config) {
mcimadamore@83 98 this.messages = messages;
mcimadamore@221 99 this.config = config;
mcimadamore@83 100 }
mcimadamore@83 101
mcimadamore@83 102 public String formatKind(JCDiagnostic d, Locale l) {
mcimadamore@83 103 switch (d.getType()) {
mcimadamore@83 104 case FRAGMENT: return "";
mcimadamore@83 105 case NOTE: return localize(l, "compiler.note.note");
mcimadamore@83 106 case WARNING: return localize(l, "compiler.warn.warning");
mcimadamore@83 107 case ERROR: return localize(l, "compiler.err.error");
mcimadamore@83 108 default:
mcimadamore@83 109 throw new AssertionError("Unknown diagnostic type: " + d.getType());
mcimadamore@83 110 }
mcimadamore@83 111 }
mcimadamore@83 112
mcimadamore@238 113 @Override
mcimadamore@238 114 public String format(JCDiagnostic d, Locale locale) {
mcimadamore@288 115 allCaptured = List.nil();
mcimadamore@238 116 return formatDiagnostic(d, locale);
mcimadamore@238 117 }
mcimadamore@238 118
mcimadamore@304 119 protected abstract String formatDiagnostic(JCDiagnostic d, Locale locale);
mcimadamore@238 120
mcimadamore@83 121 public String formatPosition(JCDiagnostic d, PositionKind pk,Locale l) {
jjg@816 122 Assert.check(d.getPosition() != Position.NOPOS);
mcimadamore@83 123 return String.valueOf(getPosition(d, pk));
mcimadamore@83 124 }
mcimadamore@221 125 //where
mcimadamore@221 126 private long getPosition(JCDiagnostic d, PositionKind pk) {
mcimadamore@83 127 switch (pk) {
mcimadamore@83 128 case START: return d.getIntStartPosition();
mcimadamore@83 129 case END: return d.getIntEndPosition();
mcimadamore@83 130 case LINE: return d.getLineNumber();
mcimadamore@83 131 case COLUMN: return d.getColumnNumber();
mcimadamore@83 132 case OFFSET: return d.getIntPosition();
mcimadamore@83 133 default:
mcimadamore@83 134 throw new AssertionError("Unknown diagnostic position: " + pk);
mcimadamore@83 135 }
mcimadamore@83 136 }
mcimadamore@83 137
mcimadamore@100 138 public String formatSource(JCDiagnostic d, boolean fullname, Locale l) {
jjg@415 139 JavaFileObject fo = d.getSource();
jjg@415 140 if (fo == null)
jjg@415 141 throw new IllegalArgumentException(); // d should have source set
jjg@415 142 if (fullname)
jjg@415 143 return fo.getName();
jjg@415 144 else if (fo instanceof BaseFileObject)
jjg@415 145 return ((BaseFileObject) fo).getShortName();
jjg@415 146 else
jjg@415 147 return BaseFileObject.getSimpleName(fo);
mcimadamore@83 148 }
mcimadamore@83 149
mcimadamore@83 150 /**
mcimadamore@83 151 * Format the arguments of a given diagnostic.
mcimadamore@83 152 *
mcimadamore@83 153 * @param d diagnostic whose arguments are to be formatted
mcimadamore@83 154 * @param l locale object to be used for i18n
mcimadamore@83 155 * @return a Collection whose elements are the formatted arguments of the diagnostic
mcimadamore@83 156 */
mcimadamore@83 157 protected Collection<String> formatArguments(JCDiagnostic d, Locale l) {
mcimadamore@83 158 ListBuffer<String> buf = new ListBuffer<String>();
mcimadamore@83 159 for (Object o : d.getArgs()) {
mcimadamore@83 160 buf.append(formatArgument(d, o, l));
mcimadamore@83 161 }
mcimadamore@83 162 return buf.toList();
mcimadamore@83 163 }
mcimadamore@83 164
mcimadamore@83 165 /**
mcimadamore@83 166 * Format a single argument of a given diagnostic.
mcimadamore@83 167 *
mcimadamore@83 168 * @param d diagnostic whose argument is to be formatted
mcimadamore@83 169 * @param arg argument to be formatted
mcimadamore@83 170 * @param l locale object to be used for i18n
mcimadamore@83 171 * @return string representation of the diagnostic argument
mcimadamore@83 172 */
mcimadamore@83 173 protected String formatArgument(JCDiagnostic d, Object arg, Locale l) {
mcimadamore@221 174 if (arg instanceof JCDiagnostic) {
mcimadamore@221 175 String s = null;
mcimadamore@221 176 depth++;
mcimadamore@221 177 try {
mcimadamore@221 178 s = formatMessage((JCDiagnostic)arg, l);
mcimadamore@221 179 }
mcimadamore@221 180 finally {
mcimadamore@221 181 depth--;
mcimadamore@221 182 }
mcimadamore@221 183 return s;
mcimadamore@221 184 }
mcimadamore@1348 185 else if (arg instanceof JCExpression) {
mcimadamore@1348 186 return expr2String((JCExpression)arg);
mcimadamore@1348 187 }
mcimadamore@83 188 else if (arg instanceof Iterable<?>) {
mcimadamore@83 189 return formatIterable(d, (Iterable<?>)arg, l);
mcimadamore@83 190 }
mcimadamore@238 191 else if (arg instanceof Type) {
mcimadamore@238 192 return printer.visit((Type)arg, l);
mcimadamore@238 193 }
mcimadamore@238 194 else if (arg instanceof Symbol) {
mcimadamore@238 195 return printer.visit((Symbol)arg, l);
mcimadamore@238 196 }
mcimadamore@238 197 else if (arg instanceof JavaFileObject) {
jjg@415 198 return ((JavaFileObject)arg).getName();
mcimadamore@238 199 }
mcimadamore@238 200 else if (arg instanceof Formattable) {
mcimadamore@136 201 return ((Formattable)arg).toString(l, messages);
mcimadamore@238 202 }
mcimadamore@238 203 else {
mcimadamore@83 204 return String.valueOf(arg);
mcimadamore@238 205 }
mcimadamore@83 206 }
mcimadamore@1348 207 //where
mcimadamore@1348 208 private String expr2String(JCExpression tree) {
mcimadamore@1348 209 switch(tree.getTag()) {
mcimadamore@1348 210 case PARENS:
mcimadamore@1348 211 return expr2String(((JCParens)tree).expr);
mcimadamore@1348 212 case LAMBDA:
mcimadamore@1352 213 case REFERENCE:
mcimadamore@1348 214 case CONDEXPR:
mcimadamore@1348 215 return Pretty.toSimpleString(tree);
mcimadamore@1348 216 default:
mcimadamore@1348 217 Assert.error("unexpected tree kind " + tree.getKind());
mcimadamore@1348 218 return null;
mcimadamore@1348 219 }
mcimadamore@1348 220 }
mcimadamore@83 221
mcimadamore@83 222 /**
mcimadamore@83 223 * Format an iterable argument of a given diagnostic.
mcimadamore@83 224 *
mcimadamore@83 225 * @param d diagnostic whose argument is to be formatted
mcimadamore@83 226 * @param it iterable argument to be formatted
mcimadamore@83 227 * @param l locale object to be used for i18n
mcimadamore@83 228 * @return string representation of the diagnostic iterable argument
mcimadamore@83 229 */
mcimadamore@83 230 protected String formatIterable(JCDiagnostic d, Iterable<?> it, Locale l) {
mcimadamore@83 231 StringBuilder sbuf = new StringBuilder();
mcimadamore@83 232 String sep = "";
mcimadamore@83 233 for (Object o : it) {
mcimadamore@83 234 sbuf.append(sep);
mcimadamore@83 235 sbuf.append(formatArgument(d, o, l));
mcimadamore@83 236 sep = ",";
mcimadamore@83 237 }
mcimadamore@83 238 return sbuf.toString();
mcimadamore@83 239 }
mcimadamore@83 240
mcimadamore@168 241 /**
mcimadamore@221 242 * Format all the subdiagnostics attached to a given diagnostic.
mcimadamore@168 243 *
mcimadamore@168 244 * @param d diagnostic whose subdiagnostics are to be formatted
mcimadamore@168 245 * @param l locale object to be used for i18n
mcimadamore@221 246 * @return list of all string representations of the subdiagnostics
mcimadamore@221 247 */
mcimadamore@221 248 protected List<String> formatSubdiagnostics(JCDiagnostic d, Locale l) {
mcimadamore@221 249 List<String> subdiagnostics = List.nil();
mcimadamore@221 250 int maxDepth = config.getMultilineLimit(MultilineLimit.DEPTH);
mcimadamore@221 251 if (maxDepth == -1 || depth < maxDepth) {
mcimadamore@221 252 depth++;
mcimadamore@221 253 try {
mcimadamore@221 254 int maxCount = config.getMultilineLimit(MultilineLimit.LENGTH);
mcimadamore@221 255 int count = 0;
mcimadamore@221 256 for (JCDiagnostic d2 : d.getSubdiagnostics()) {
mcimadamore@221 257 if (maxCount == -1 || count < maxCount) {
mcimadamore@221 258 subdiagnostics = subdiagnostics.append(formatSubdiagnostic(d, d2, l));
mcimadamore@221 259 count++;
mcimadamore@221 260 }
mcimadamore@221 261 else
mcimadamore@221 262 break;
mcimadamore@221 263 }
mcimadamore@221 264 }
mcimadamore@221 265 finally {
mcimadamore@221 266 depth--;
mcimadamore@221 267 }
mcimadamore@221 268 }
mcimadamore@221 269 return subdiagnostics;
mcimadamore@221 270 }
mcimadamore@221 271
mcimadamore@221 272 /**
mcimadamore@221 273 * Format a subdiagnostics attached to a given diagnostic.
mcimadamore@221 274 *
mcimadamore@221 275 * @param parent multiline diagnostic whose subdiagnostics is to be formatted
mcimadamore@221 276 * @param sub subdiagnostic to be formatted
mcimadamore@221 277 * @param l locale object to be used for i18n
mcimadamore@168 278 * @return string representation of the subdiagnostics
mcimadamore@168 279 */
mcimadamore@221 280 protected String formatSubdiagnostic(JCDiagnostic parent, JCDiagnostic sub, Locale l) {
mcimadamore@221 281 return formatMessage(sub, l);
mcimadamore@168 282 }
mcimadamore@168 283
mcimadamore@137 284 /** Format the faulty source code line and point to the error.
mcimadamore@137 285 * @param d The diagnostic for which the error line should be printed
mcimadamore@137 286 */
mcimadamore@221 287 protected String formatSourceLine(JCDiagnostic d, int nSpaces) {
mcimadamore@137 288 StringBuilder buf = new StringBuilder();
mcimadamore@137 289 DiagnosticSource source = d.getDiagnosticSource();
mcimadamore@137 290 int pos = d.getIntPosition();
mcimadamore@221 291 if (d.getIntPosition() == Position.NOPOS)
mcimadamore@221 292 throw new AssertionError();
mcimadamore@221 293 String line = (source == null ? null : source.getLine(pos));
mcimadamore@221 294 if (line == null)
mcimadamore@221 295 return "";
mcimadamore@221 296 buf.append(indent(line, nSpaces));
mcimadamore@221 297 int col = source.getColumnNumber(pos, false);
mcimadamore@221 298 if (config.isCaretEnabled()) {
mcimadamore@221 299 buf.append("\n");
mcimadamore@137 300 for (int i = 0; i < col - 1; i++) {
mcimadamore@137 301 buf.append((line.charAt(i) == '\t') ? "\t" : " ");
mcimadamore@137 302 }
mcimadamore@221 303 buf.append(indent("^", nSpaces));
mcimadamore@221 304 }
mcimadamore@221 305 return buf.toString();
mcimadamore@137 306 }
mcimadamore@137 307
jjg@612 308 protected String formatLintCategory(JCDiagnostic d, Locale l) {
jjg@612 309 LintCategory lc = d.getLintCategory();
jjg@612 310 if (lc == null)
jjg@612 311 return "";
jjg@612 312 return localize(l, "compiler.warn.lintOption", lc.option);
jjg@612 313 }
jjg@612 314
mcimadamore@83 315 /**
mcimadamore@221 316 * Converts a String into a locale-dependent representation accordingly to a given locale.
mcimadamore@83 317 *
mcimadamore@83 318 * @param l locale object to be used for i18n
mcimadamore@83 319 * @param key locale-independent key used for looking up in a resource file
mcimadamore@83 320 * @param args localization arguments
mcimadamore@83 321 * @return a locale-dependent string
mcimadamore@83 322 */
mcimadamore@83 323 protected String localize(Locale l, String key, Object... args) {
mcimadamore@136 324 return messages.getLocalizedString(l, key, args);
mcimadamore@83 325 }
mcimadamore@137 326
mcimadamore@137 327 public boolean displaySource(JCDiagnostic d) {
mcimadamore@221 328 return config.getVisible().contains(DiagnosticPart.SOURCE) &&
mcimadamore@221 329 d.getType() != FRAGMENT &&
mcimadamore@221 330 d.getIntPosition() != Position.NOPOS;
mcimadamore@137 331 }
mcimadamore@168 332
mcimadamore@288 333 public boolean isRaw() {
mcimadamore@288 334 return false;
mcimadamore@288 335 }
mcimadamore@288 336
mcimadamore@168 337 /**
mcimadamore@168 338 * Creates a string with a given amount of empty spaces. Useful for
mcimadamore@168 339 * indenting the text of a diagnostic message.
mcimadamore@168 340 *
mcimadamore@168 341 * @param nSpaces the amount of spaces to be added to the result string
mcimadamore@168 342 * @return the indentation string
mcimadamore@168 343 */
mcimadamore@168 344 protected String indentString(int nSpaces) {
mcimadamore@168 345 String spaces = " ";
mcimadamore@168 346 if (nSpaces <= spaces.length())
mcimadamore@168 347 return spaces.substring(0, nSpaces);
mcimadamore@168 348 else {
mcimadamore@168 349 StringBuilder buf = new StringBuilder();
mcimadamore@168 350 for (int i = 0 ; i < nSpaces ; i++)
mcimadamore@168 351 buf.append(" ");
mcimadamore@168 352 return buf.toString();
mcimadamore@168 353 }
mcimadamore@168 354 }
mcimadamore@168 355
mcimadamore@168 356 /**
mcimadamore@168 357 * Indent a string by prepending a given amount of empty spaces to each line
mcimadamore@221 358 * of the string.
mcimadamore@168 359 *
mcimadamore@168 360 * @param s the string to be indented
mcimadamore@168 361 * @param nSpaces the amount of spaces that should be prepended to each line
mcimadamore@168 362 * of the string
mcimadamore@168 363 * @return an indented string
mcimadamore@168 364 */
mcimadamore@168 365 protected String indent(String s, int nSpaces) {
mcimadamore@168 366 String indent = indentString(nSpaces);
mcimadamore@168 367 StringBuilder buf = new StringBuilder();
mcimadamore@168 368 String nl = "";
mcimadamore@168 369 for (String line : s.split("\n")) {
mcimadamore@168 370 buf.append(nl);
mcimadamore@168 371 buf.append(indent + line);
mcimadamore@168 372 nl = "\n";
mcimadamore@168 373 }
mcimadamore@168 374 return buf.toString();
mcimadamore@168 375 }
mcimadamore@221 376
mcimadamore@221 377 public SimpleConfiguration getConfiguration() {
mcimadamore@221 378 return config;
mcimadamore@221 379 }
mcimadamore@221 380
mcimadamore@221 381 static public class SimpleConfiguration implements Configuration {
mcimadamore@221 382
mcimadamore@221 383 protected Map<MultilineLimit, Integer> multilineLimits;
mcimadamore@221 384 protected EnumSet<DiagnosticPart> visibleParts;
mcimadamore@221 385 protected boolean caretEnabled;
mcimadamore@221 386
mcimadamore@221 387 public SimpleConfiguration(Set<DiagnosticPart> parts) {
mcimadamore@221 388 multilineLimits = new HashMap<MultilineLimit, Integer>();
mcimadamore@221 389 setVisible(parts);
mcimadamore@221 390 setMultilineLimit(MultilineLimit.DEPTH, -1);
mcimadamore@221 391 setMultilineLimit(MultilineLimit.LENGTH, -1);
mcimadamore@221 392 setCaretEnabled(true);
mcimadamore@221 393 }
mcimadamore@221 394
mcimadamore@221 395 @SuppressWarnings("fallthrough")
mcimadamore@221 396 public SimpleConfiguration(Options options, Set<DiagnosticPart> parts) {
mcimadamore@221 397 this(parts);
mcimadamore@221 398 String showSource = null;
mcimadamore@221 399 if ((showSource = options.get("showSource")) != null) {
mcimadamore@221 400 if (showSource.equals("true"))
mcimadamore@288 401 setVisiblePart(DiagnosticPart.SOURCE, true);
mcimadamore@221 402 else if (showSource.equals("false"))
mcimadamore@288 403 setVisiblePart(DiagnosticPart.SOURCE, false);
mcimadamore@221 404 }
mcimadamore@221 405 String diagOpts = options.get("diags");
mcimadamore@221 406 if (diagOpts != null) {//override -XDshowSource
mcimadamore@221 407 Collection<String> args = Arrays.asList(diagOpts.split(","));
mcimadamore@221 408 if (args.contains("short")) {
mcimadamore@288 409 setVisiblePart(DiagnosticPart.DETAILS, false);
mcimadamore@288 410 setVisiblePart(DiagnosticPart.SUBDIAGNOSTICS, false);
mcimadamore@221 411 }
mcimadamore@221 412 if (args.contains("source"))
mcimadamore@288 413 setVisiblePart(DiagnosticPart.SOURCE, true);
mcimadamore@221 414 if (args.contains("-source"))
mcimadamore@288 415 setVisiblePart(DiagnosticPart.SOURCE, false);
mcimadamore@221 416 }
mcimadamore@221 417 String multiPolicy = null;
mcimadamore@221 418 if ((multiPolicy = options.get("multilinePolicy")) != null) {
mcimadamore@221 419 if (multiPolicy.equals("disabled"))
mcimadamore@288 420 setVisiblePart(DiagnosticPart.SUBDIAGNOSTICS, false);
mcimadamore@221 421 else if (multiPolicy.startsWith("limit:")) {
mcimadamore@221 422 String limitString = multiPolicy.substring("limit:".length());
mcimadamore@221 423 String[] limits = limitString.split(":");
mcimadamore@221 424 try {
mcimadamore@221 425 switch (limits.length) {
mcimadamore@221 426 case 2: {
mcimadamore@221 427 if (!limits[1].equals("*"))
mcimadamore@221 428 setMultilineLimit(MultilineLimit.DEPTH, Integer.parseInt(limits[1]));
mcimadamore@221 429 }
mcimadamore@221 430 case 1: {
mcimadamore@221 431 if (!limits[0].equals("*"))
mcimadamore@221 432 setMultilineLimit(MultilineLimit.LENGTH, Integer.parseInt(limits[0]));
mcimadamore@221 433 }
mcimadamore@221 434 }
mcimadamore@221 435 }
mcimadamore@221 436 catch(NumberFormatException ex) {
mcimadamore@221 437 setMultilineLimit(MultilineLimit.DEPTH, -1);
mcimadamore@221 438 setMultilineLimit(MultilineLimit.LENGTH, -1);
mcimadamore@221 439 }
mcimadamore@221 440 }
mcimadamore@221 441 }
mcimadamore@221 442 String showCaret = null;
mcimadamore@221 443 if (((showCaret = options.get("showCaret")) != null) &&
mcimadamore@221 444 showCaret.equals("false"))
mcimadamore@221 445 setCaretEnabled(false);
mcimadamore@221 446 else
mcimadamore@221 447 setCaretEnabled(true);
mcimadamore@221 448 }
mcimadamore@221 449
mcimadamore@221 450 public int getMultilineLimit(MultilineLimit limit) {
mcimadamore@221 451 return multilineLimits.get(limit);
mcimadamore@221 452 }
mcimadamore@221 453
mcimadamore@221 454 public EnumSet<DiagnosticPart> getVisible() {
mcimadamore@221 455 return EnumSet.copyOf(visibleParts);
mcimadamore@221 456 }
mcimadamore@221 457
mcimadamore@221 458 public void setMultilineLimit(MultilineLimit limit, int value) {
mcimadamore@221 459 multilineLimits.put(limit, value < -1 ? -1 : value);
mcimadamore@221 460 }
mcimadamore@221 461
mcimadamore@221 462
mcimadamore@221 463 public void setVisible(Set<DiagnosticPart> diagParts) {
mcimadamore@221 464 visibleParts = EnumSet.copyOf(diagParts);
mcimadamore@221 465 }
mcimadamore@221 466
mcimadamore@288 467 public void setVisiblePart(DiagnosticPart diagParts, boolean enabled) {
mcimadamore@288 468 if (enabled)
mcimadamore@288 469 visibleParts.add(diagParts);
mcimadamore@288 470 else
mcimadamore@288 471 visibleParts.remove(diagParts);
mcimadamore@288 472 }
mcimadamore@288 473
mcimadamore@221 474 /**
mcimadamore@221 475 * Shows a '^' sign under the source line displayed by the formatter
mcimadamore@221 476 * (if applicable).
mcimadamore@221 477 *
mcimadamore@221 478 * @param caretEnabled if true enables caret
mcimadamore@221 479 */
mcimadamore@221 480 public void setCaretEnabled(boolean caretEnabled) {
mcimadamore@221 481 this.caretEnabled = caretEnabled;
mcimadamore@221 482 }
mcimadamore@221 483
mcimadamore@221 484 /**
mcimadamore@221 485 * Tells whether the caret display is active or not.
mcimadamore@221 486 *
jjg@1358 487 * @return true if the caret is enabled
mcimadamore@221 488 */
mcimadamore@221 489 public boolean isCaretEnabled() {
mcimadamore@221 490 return caretEnabled;
mcimadamore@221 491 }
mcimadamore@221 492 }
mcimadamore@238 493
mcimadamore@288 494 public Printer getPrinter() {
mcimadamore@288 495 return printer;
mcimadamore@288 496 }
mcimadamore@288 497
mcimadamore@288 498 public void setPrinter(Printer printer) {
mcimadamore@288 499 this.printer = printer;
mcimadamore@288 500 }
mcimadamore@288 501
mcimadamore@238 502 /**
mcimadamore@238 503 * An enhanced printer for formatting types/symbols used by
mcimadamore@238 504 * AbstractDiagnosticFormatter. Provides alternate numbering of captured
mcimadamore@238 505 * types (they are numbered starting from 1 on each new diagnostic, instead
mcimadamore@238 506 * of relying on the underlying hashcode() method which generates unstable
mcimadamore@238 507 * output). Also detects cycles in wildcard messages (e.g. if the wildcard
mcimadamore@238 508 * type referred by a given captured type C contains C itself) which might
mcimadamore@238 509 * lead to infinite loops.
mcimadamore@238 510 */
mcimadamore@1348 511 protected Printer printer = new Printer() {
mcimadamore@1347 512
mcimadamore@238 513 @Override
mcimadamore@238 514 protected String localize(Locale locale, String key, Object... args) {
mcimadamore@238 515 return AbstractDiagnosticFormatter.this.localize(locale, key, args);
mcimadamore@238 516 }
mcimadamore@238 517 @Override
mcimadamore@288 518 protected String capturedVarId(CapturedType t, Locale locale) {
mcimadamore@288 519 return "" + (allCaptured.indexOf(t) + 1);
mcimadamore@238 520 }
mcimadamore@296 521 @Override
mcimadamore@296 522 public String visitCapturedType(CapturedType t, Locale locale) {
mcimadamore@296 523 if (!allCaptured.contains(t)) {
mcimadamore@296 524 allCaptured = allCaptured.append(t);
mcimadamore@296 525 }
mcimadamore@296 526 return super.visitCapturedType(t, locale);
mcimadamore@296 527 }
mcimadamore@288 528 };
mcimadamore@83 529 }

mercurial