1 /* 2 * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime; 27 28 import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError; 29 30 import java.io.PrintWriter; 31 import jdk.nashorn.internal.parser.Token; 32 33 /** 34 * Handles JavaScript error reporting. 35 */ 36 public class ErrorManager { 37 // TODO - collect and sort/collapse error messages. 38 // TODO - property based error messages. 39 /** Reporting writer. */ 40 private final PrintWriter writer; 41 42 /** Error count. */ 43 private int errors; 44 45 /** Warning count */ 46 private int warnings; 47 48 /** Limit of the number of messages. */ 49 private int limit; 50 51 /** Treat warnings as errors. */ 52 private boolean warningsAsErrors; 53 54 /** 55 * Constructor 56 */ 57 public ErrorManager() { 58 this(new PrintWriter(System.err, true)); //bootstrapping, context may not be initialized 59 } 60 61 /** 62 * Constructor. 63 * @param writer I/O writer to report on. 64 */ 65 public ErrorManager(final PrintWriter writer) { 66 this.writer = writer; 67 this.limit = 100; 68 this.warningsAsErrors = false; 69 } 70 71 /** 72 * Check to see if number of errors exceed limit. 73 */ 74 private void checkLimit() { 75 int count = errors; 76 77 if (warningsAsErrors) { 78 count += warnings; 79 } 80 81 if (limit != 0 && count > limit) { 82 throw rangeError("too.many.errors", Integer.toString(limit)); 83 } 84 } 85 86 /** 87 * Format an error message to include source and line information. 88 * @param message Error message string. 89 * @param source Source file information. 90 * @param line Source line number. 91 * @param column Source column number. 92 * @param token Offending token descriptor. 93 * @return formatted string 94 */ 95 public static String format(final String message, final Source source, final int line, final int column, final long token) { 96 final String eoln = System.lineSeparator(); 97 final int position = Token.descPosition(token); 98 final StringBuilder sb = new StringBuilder(); 99 100 // Source description and message. 101 sb.append(source.getName()). 102 append(':'). 103 append(line). 104 append(':'). 105 append(column). 106 append(' '). 107 append(message). 108 append(eoln); 109 110 // Source content. 111 final String sourceLine = source.getSourceLine(position); 112 sb.append(sourceLine).append(eoln); 113 114 // Pointer to column. 115 for (int i = 0; i < column; i++) { 116 if (i < sourceLine.length() && sourceLine.charAt(i) == '\t') { 117 sb.append('\t'); 118 } else { 119 sb.append(' '); 120 } 121 } 122 123 sb.append('^'); 124 // Use will append eoln. 125 // buffer.append(eoln); 126 127 return sb.toString(); 128 } 129 130 /** 131 * Report an error using information provided by the ParserException 132 * 133 * @param e ParserException object 134 */ 135 136 public void error(final ParserException e) { 137 error(e.getMessage()); 138 } 139 140 /** 141 * Report an error message provided 142 * 143 * @param message Error message string. 144 */ 145 public void error(final String message) { 146 writer.println(message); 147 writer.flush(); 148 errors++; 149 checkLimit(); 150 } 151 152 /** 153 * Report a warning using information provided by the ParserException 154 * 155 * @param e ParserException object 156 */ 157 public void warning(final ParserException e) { 158 warning(e.getMessage()); 159 } 160 161 /** 162 * Report a warning message provided 163 * 164 * @param message Error message string. 165 */ 166 public void warning(final String message) { 167 writer.println(message); 168 writer.flush(); 169 warnings++; 170 checkLimit(); 171 } 172 173 /** 174 * Test to see if errors have occurred. 175 * @return True if errors. 176 */ 177 public boolean hasErrors() { 178 return errors != 0; 179 } 180 181 /** 182 * Get the message limit 183 * @return max number of messages 184 */ 185 public int getLimit() { 186 return limit; 187 } 188 189 /** 190 * Set the message limit 191 * @param limit max number of messages 192 */ 193 public void setLimit(final int limit) { 194 this.limit = limit; 195 } 196 197 /** 198 * Check whether warnings should be treated like errors 199 * @return true if warnings should be treated like errors 200 */ 201 public boolean isWarningsAsErrors() { 202 return warningsAsErrors; 203 } 204 205 /** 206 * Set warnings to be treated as errors 207 * @param warningsAsErrors true if warnings should be treated as errors, false otherwise 208 */ 209 public void setWarningsAsErrors(final boolean warningsAsErrors) { 210 this.warningsAsErrors = warningsAsErrors; 211 } 212 213 /** 214 * Get the number of errors 215 * @return number of errors 216 */ 217 public int getNumberOfErrors() { 218 return errors; 219 } 220 221 /** 222 * Get number of warnings 223 * @return number of warnings 224 */ 225 public int getNumberOfWarnings() { 226 return warnings; 227 } 228 229 /** 230 * Clear warnings and error count. 231 */ 232 void reset() { 233 warnings = 0; 234 errors = 0; 235 } 236 }