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

Tue, 28 Dec 2010 15:54:52 -0800

author
ohair
date
Tue, 28 Dec 2010 15:54:52 -0800
changeset 798
4868a36f6fd8
parent 581
f2fdd52e4e87
child 1138
7375d4979bd3
permissions
-rw-r--r--

6962318: Update copyright year
Reviewed-by: xdono

jjg@73 1 /*
ohair@554 2 * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
jjg@73 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jjg@73 4 *
jjg@73 5 * This code is free software; you can redistribute it and/or modify it
jjg@73 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
jjg@73 8 * particular file as subject to the "Classpath" exception as provided
ohair@554 9 * by Oracle in the LICENSE file that accompanied this code.
jjg@73 10 *
jjg@73 11 * This code is distributed in the hope that it will be useful, but WITHOUT
jjg@73 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jjg@73 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jjg@73 14 * version 2 for more details (a copy is included in the LICENSE file that
jjg@73 15 * accompanied this code).
jjg@73 16 *
jjg@73 17 * You should have received a copy of the GNU General Public License version
jjg@73 18 * 2 along with this work; if not, write to the Free Software Foundation,
jjg@73 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jjg@73 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.
jjg@73 24 */
jjg@73 25
jjg@73 26 package com.sun.tools.javac.util;
jjg@73 27
jjg@73 28 import java.io.IOException;
jjg@73 29 import java.lang.ref.SoftReference;
jjg@73 30 import java.nio.CharBuffer;
jjg@73 31 import java.util.Map;
jjg@73 32 import javax.tools.JavaFileObject;
jjg@73 33
jjg@73 34 import com.sun.tools.javac.file.JavacFileManager;
jjg@73 35 import com.sun.tools.javac.tree.JCTree;
jjg@73 36
jjg@73 37 import static com.sun.tools.javac.util.LayoutCharacters.*;
jjg@73 38
jjg@73 39 /**
jjg@73 40 * A simple abstraction of a source file, as needed for use in a diagnostic message.
jjg@73 41 * Provides access to the line and position in a line for any given character offset.
jjg@73 42 *
jjg@581 43 * <p><b>This is NOT part of any supported API.
jjg@581 44 * If you write code that depends on this, you do so at your own risk.
jjg@73 45 * This code and its internal interfaces are subject to change or
jjg@73 46 * deletion without notice.</b>
jjg@73 47 */
jjg@73 48 public class DiagnosticSource {
mcimadamore@303 49
mcimadamore@303 50 /* constant DiagnosticSource to be used when sourcefile is missing */
mcimadamore@303 51 public static final DiagnosticSource NO_SOURCE = new DiagnosticSource() {
mcimadamore@303 52 @Override
mcimadamore@303 53 protected boolean findLine(int pos) {
mcimadamore@303 54 return false;
mcimadamore@303 55 }
mcimadamore@303 56 };
mcimadamore@303 57
jjg@73 58 public DiagnosticSource(JavaFileObject fo, AbstractLog log) {
jjg@73 59 this.fileObject = fo;
jjg@73 60 this.log = log;
jjg@73 61 }
jjg@73 62
mcimadamore@303 63 private DiagnosticSource() {}
mcimadamore@303 64
jjg@73 65 /** Return the underlying file object handled by this
jjg@73 66 * DiagnosticSource object.
jjg@73 67 */
jjg@73 68 public JavaFileObject getFile() {
jjg@73 69 return fileObject;
jjg@73 70 }
jjg@73 71
jjg@73 72 /** Return the one-based line number associated with a given pos
jjg@73 73 * for the current source file. Zero is returned if no line exists
jjg@73 74 * for the given position.
jjg@73 75 */
jjg@73 76 public int getLineNumber(int pos) {
jjg@73 77 try {
jjg@73 78 if (findLine(pos)) {
jjg@73 79 return line;
jjg@73 80 }
jjg@73 81 return 0;
jjg@73 82 } finally {
jjg@73 83 buf = null;
jjg@73 84 }
jjg@73 85 }
jjg@73 86
jjg@73 87 /** Return the one-based column number associated with a given pos
jjg@73 88 * for the current source file. Zero is returned if no column exists
jjg@73 89 * for the given position.
jjg@73 90 */
mcimadamore@100 91 public int getColumnNumber(int pos, boolean expandTabs) {
jjg@73 92 try {
jjg@73 93 if (findLine(pos)) {
jjg@73 94 int column = 0;
jjg@73 95 for (int bp = lineStart; bp < pos; bp++) {
jjg@73 96 if (bp >= bufLen) {
jjg@73 97 return 0;
jjg@73 98 }
mcimadamore@100 99 if (buf[bp] == '\t' && expandTabs) {
jjg@73 100 column = (column / TabInc * TabInc) + TabInc;
jjg@73 101 } else {
jjg@73 102 column++;
jjg@73 103 }
jjg@73 104 }
jjg@73 105 return column + 1; // positions are one-based
jjg@73 106 }
jjg@73 107 return 0;
jjg@73 108 } finally {
jjg@73 109 buf = null;
jjg@73 110 }
jjg@73 111 }
jjg@73 112
jjg@73 113 /** Return the content of the line containing a given pos.
jjg@73 114 */
jjg@73 115 public String getLine(int pos) {
jjg@73 116 try {
jjg@73 117 if (!findLine(pos))
jjg@73 118 return null;
jjg@73 119
jjg@73 120 int lineEnd = lineStart;
jjg@73 121 while (lineEnd < bufLen && buf[lineEnd] != CR && buf[lineEnd] != LF)
jjg@73 122 lineEnd++;
jjg@73 123 if (lineEnd - lineStart == 0)
jjg@73 124 return null;
jjg@73 125 return new String(buf, lineStart, lineEnd - lineStart);
jjg@73 126 } finally {
jjg@73 127 buf = null;
jjg@73 128 }
jjg@73 129 }
jjg@73 130
jjg@73 131 public Map<JCTree, Integer> getEndPosTable() {
jjg@73 132 return endPosTable;
jjg@73 133 }
jjg@73 134
jjg@73 135 public void setEndPosTable(Map<JCTree, Integer> t) {
jjg@73 136 if (endPosTable != null && endPosTable != t)
jjg@73 137 throw new IllegalStateException("endPosTable already set");
jjg@73 138 endPosTable = t;
jjg@73 139 }
jjg@73 140
jjg@73 141 /** Find the line in the buffer that contains the current position
jjg@73 142 * @param pos Character offset into the buffer
jjg@73 143 */
mcimadamore@303 144 protected boolean findLine(int pos) {
jjg@73 145 if (pos == Position.NOPOS)
jjg@73 146 return false;
jjg@73 147
jjg@73 148 try {
jjg@73 149 // try and recover buffer from soft reference cache
jjg@73 150 if (buf == null && refBuf != null)
jjg@73 151 buf = refBuf.get();
jjg@73 152
jjg@73 153 if (buf == null) {
jjg@73 154 buf = initBuf(fileObject);
jjg@73 155 lineStart = 0;
jjg@73 156 line = 1;
jjg@73 157 } else if (lineStart > pos) { // messages don't come in order
jjg@73 158 lineStart = 0;
jjg@73 159 line = 1;
jjg@73 160 }
jjg@73 161
jjg@73 162 int bp = lineStart;
jjg@73 163 while (bp < bufLen && bp < pos) {
jjg@73 164 switch (buf[bp++]) {
jjg@73 165 case CR:
jjg@73 166 if (bp < bufLen && buf[bp] == LF) bp++;
jjg@73 167 line++;
jjg@73 168 lineStart = bp;
jjg@73 169 break;
jjg@73 170 case LF:
jjg@73 171 line++;
jjg@73 172 lineStart = bp;
jjg@73 173 break;
jjg@73 174 }
jjg@73 175 }
jjg@73 176 return bp <= bufLen;
jjg@73 177 } catch (IOException e) {
jjg@73 178 log.directError("source.unavailable");
jjg@73 179 buf = new char[0];
jjg@73 180 return false;
jjg@73 181 }
jjg@73 182 }
jjg@73 183
jjg@73 184 protected char[] initBuf(JavaFileObject fileObject) throws IOException {
jjg@73 185 char[] buf;
jjg@73 186 CharSequence cs = fileObject.getCharContent(true);
jjg@73 187 if (cs instanceof CharBuffer) {
jjg@73 188 CharBuffer cb = (CharBuffer) cs;
jjg@73 189 buf = JavacFileManager.toArray(cb);
jjg@73 190 bufLen = cb.limit();
jjg@73 191 } else {
jjg@73 192 buf = cs.toString().toCharArray();
jjg@73 193 bufLen = buf.length;
jjg@73 194 }
jjg@73 195 refBuf = new SoftReference<char[]>(buf);
jjg@73 196 return buf;
jjg@73 197 }
jjg@73 198
jjg@73 199 /** The underlying file object. */
jjg@73 200 protected JavaFileObject fileObject;
jjg@73 201
jjg@73 202 protected Map<JCTree, Integer> endPosTable;
jjg@73 203
jjg@73 204 /** A soft reference to the content of the file object. */
jjg@73 205 protected SoftReference<char[]> refBuf;
jjg@73 206
jjg@73 207 /** A temporary hard reference to the content of the file object. */
jjg@73 208 protected char[] buf;
jjg@73 209
jjg@73 210 /** The length of the content. */
jjg@73 211 protected int bufLen;
jjg@73 212
jjg@73 213 /** The start of a line found by findLine. */
jjg@73 214 protected int lineStart;
jjg@73 215
jjg@73 216 /** The line number of a line found by findLine. */
jjg@73 217 protected int line;
jjg@73 218
jjg@73 219 /** A log for reporting errors, such as errors accessing the content. */
jjg@73 220 protected AbstractLog log;
jjg@73 221 }

mercurial