001 /* 002 * Copyright 2007 Google Inc. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy of 006 * the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 */ 016 package com.google.gwt.dev.js; 017 018 /** 019 * Indicates inability to parse JavaScript source. 020 */ 021 public class JsParserException extends Exception { 022 023 /** 024 * Represents the location of a parser exception. 025 */ 026 public static class SourceDetail { 027 private final String fileName; 028 private final int line; 029 private final int lineOffset; 030 private final String lineSource; 031 032 public SourceDetail(int line, String lineSource, int lineOffset, 033 String fileName) { 034 this.line = line; 035 this.lineSource = lineSource; 036 this.lineOffset = lineOffset; 037 this.fileName = fileName; 038 } 039 040 public String getFileName() { 041 return fileName; 042 } 043 044 public int getLine() { 045 return line; 046 } 047 048 public int getLineOffset() { 049 return lineOffset; 050 } 051 052 public String getLineSource() { 053 return lineSource; 054 } 055 } 056 057 private static String createMessageWithDetail(String msg, 058 SourceDetail sourceDetail) { 059 if (sourceDetail == null) { 060 return msg; 061 } 062 StringBuffer sb = new StringBuffer(); 063 sb.append(sourceDetail.getFileName()); 064 sb.append('('); 065 sb.append(sourceDetail.getLine()); 066 sb.append(')'); 067 sb.append(": "); 068 sb.append(msg); 069 if (sourceDetail.getLineSource() != null) { 070 sb.append("\n> "); 071 sb.append(sourceDetail.getLineSource()); 072 sb.append("\n> "); 073 for (int i = 0, n = sourceDetail.getLineOffset(); i < n; ++i) { 074 sb.append('-'); 075 } 076 sb.append('^'); 077 } 078 return sb.toString(); 079 } 080 081 private final SourceDetail sourceDetail; 082 083 public JsParserException(String msg) { 084 this(msg, null); 085 } 086 087 public JsParserException(String msg, int line, String lineSource, 088 int lineOffset, String fileName) { 089 this(msg, new SourceDetail(line, lineSource, lineOffset, fileName)); 090 } 091 092 public JsParserException(String msg, SourceDetail sourceDetail) { 093 super(createMessageWithDetail(msg, sourceDetail)); 094 this.sourceDetail = sourceDetail; 095 } 096 097 /** 098 * Provides additional source detail in some cases. 099 * 100 * @return additional detail regarding the error, or <code>null</code> if no 101 * additional detail is available 102 */ 103 public SourceDetail getSourceDetail() { 104 return sourceDetail; 105 } 106 }