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

Tue, 09 Oct 2012 19:10:00 -0700

author
jjg
date
Tue, 09 Oct 2012 19:10:00 -0700
changeset 1357
c75be5bc5283
parent 1280
5c0b3faeb0b0
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8000663: clean up langtools imports
Reviewed-by: darcy

jjg@73 1 /*
jjg@1280 2 * Copyright (c) 1999, 2012, 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 javax.tools.JavaFileObject;
jjg@73 32
jjg@73 33 import com.sun.tools.javac.file.JavacFileManager;
jjg@1280 34 import com.sun.tools.javac.tree.EndPosTable;
jjg@73 35
jjg@73 36 import static com.sun.tools.javac.util.LayoutCharacters.*;
jjg@73 37
jjg@73 38 /**
jjg@73 39 * A simple abstraction of a source file, as needed for use in a diagnostic message.
jjg@73 40 * Provides access to the line and position in a line for any given character offset.
jjg@73 41 *
jjg@581 42 * <p><b>This is NOT part of any supported API.
jjg@581 43 * If you write code that depends on this, you do so at your own risk.
jjg@73 44 * This code and its internal interfaces are subject to change or
jjg@73 45 * deletion without notice.</b>
jjg@73 46 */
jjg@73 47 public class DiagnosticSource {
mcimadamore@303 48
mcimadamore@303 49 /* constant DiagnosticSource to be used when sourcefile is missing */
mcimadamore@303 50 public static final DiagnosticSource NO_SOURCE = new DiagnosticSource() {
mcimadamore@303 51 @Override
mcimadamore@303 52 protected boolean findLine(int pos) {
mcimadamore@303 53 return false;
mcimadamore@303 54 }
mcimadamore@303 55 };
mcimadamore@303 56
jjg@73 57 public DiagnosticSource(JavaFileObject fo, AbstractLog log) {
jjg@73 58 this.fileObject = fo;
jjg@73 59 this.log = log;
jjg@73 60 }
jjg@73 61
mcimadamore@303 62 private DiagnosticSource() {}
mcimadamore@303 63
jjg@73 64 /** Return the underlying file object handled by this
jjg@73 65 * DiagnosticSource object.
jjg@73 66 */
jjg@73 67 public JavaFileObject getFile() {
jjg@73 68 return fileObject;
jjg@73 69 }
jjg@73 70
jjg@73 71 /** Return the one-based line number associated with a given pos
jjg@73 72 * for the current source file. Zero is returned if no line exists
jjg@73 73 * for the given position.
jjg@73 74 */
jjg@73 75 public int getLineNumber(int pos) {
jjg@73 76 try {
jjg@73 77 if (findLine(pos)) {
jjg@73 78 return line;
jjg@73 79 }
jjg@73 80 return 0;
jjg@73 81 } finally {
jjg@73 82 buf = null;
jjg@73 83 }
jjg@73 84 }
jjg@73 85
jjg@73 86 /** Return the one-based column number associated with a given pos
jjg@73 87 * for the current source file. Zero is returned if no column exists
jjg@73 88 * for the given position.
jjg@73 89 */
mcimadamore@100 90 public int getColumnNumber(int pos, boolean expandTabs) {
jjg@73 91 try {
jjg@73 92 if (findLine(pos)) {
jjg@73 93 int column = 0;
jjg@73 94 for (int bp = lineStart; bp < pos; bp++) {
jjg@73 95 if (bp >= bufLen) {
jjg@73 96 return 0;
jjg@73 97 }
mcimadamore@100 98 if (buf[bp] == '\t' && expandTabs) {
jjg@73 99 column = (column / TabInc * TabInc) + TabInc;
jjg@73 100 } else {
jjg@73 101 column++;
jjg@73 102 }
jjg@73 103 }
jjg@73 104 return column + 1; // positions are one-based
jjg@73 105 }
jjg@73 106 return 0;
jjg@73 107 } finally {
jjg@73 108 buf = null;
jjg@73 109 }
jjg@73 110 }
jjg@73 111
jjg@73 112 /** Return the content of the line containing a given pos.
jjg@73 113 */
jjg@73 114 public String getLine(int pos) {
jjg@73 115 try {
jjg@73 116 if (!findLine(pos))
jjg@73 117 return null;
jjg@73 118
jjg@73 119 int lineEnd = lineStart;
jjg@73 120 while (lineEnd < bufLen && buf[lineEnd] != CR && buf[lineEnd] != LF)
jjg@73 121 lineEnd++;
jjg@73 122 if (lineEnd - lineStart == 0)
jjg@73 123 return null;
jjg@73 124 return new String(buf, lineStart, lineEnd - lineStart);
jjg@73 125 } finally {
jjg@73 126 buf = null;
jjg@73 127 }
jjg@73 128 }
jjg@73 129
ksrini@1138 130 public EndPosTable getEndPosTable() {
jjg@73 131 return endPosTable;
jjg@73 132 }
jjg@73 133
ksrini@1138 134 public void setEndPosTable(EndPosTable t) {
jjg@73 135 if (endPosTable != null && endPosTable != t)
jjg@73 136 throw new IllegalStateException("endPosTable already set");
jjg@73 137 endPosTable = t;
jjg@73 138 }
jjg@73 139
jjg@73 140 /** Find the line in the buffer that contains the current position
jjg@73 141 * @param pos Character offset into the buffer
jjg@73 142 */
mcimadamore@303 143 protected boolean findLine(int pos) {
jjg@73 144 if (pos == Position.NOPOS)
jjg@73 145 return false;
jjg@73 146
jjg@73 147 try {
jjg@73 148 // try and recover buffer from soft reference cache
jjg@73 149 if (buf == null && refBuf != null)
jjg@73 150 buf = refBuf.get();
jjg@73 151
jjg@73 152 if (buf == null) {
jjg@73 153 buf = initBuf(fileObject);
jjg@73 154 lineStart = 0;
jjg@73 155 line = 1;
jjg@73 156 } else if (lineStart > pos) { // messages don't come in order
jjg@73 157 lineStart = 0;
jjg@73 158 line = 1;
jjg@73 159 }
jjg@73 160
jjg@73 161 int bp = lineStart;
jjg@73 162 while (bp < bufLen && bp < pos) {
jjg@73 163 switch (buf[bp++]) {
jjg@73 164 case CR:
jjg@73 165 if (bp < bufLen && buf[bp] == LF) bp++;
jjg@73 166 line++;
jjg@73 167 lineStart = bp;
jjg@73 168 break;
jjg@73 169 case LF:
jjg@73 170 line++;
jjg@73 171 lineStart = bp;
jjg@73 172 break;
jjg@73 173 }
jjg@73 174 }
jjg@73 175 return bp <= bufLen;
jjg@73 176 } catch (IOException e) {
jjg@73 177 log.directError("source.unavailable");
jjg@73 178 buf = new char[0];
jjg@73 179 return false;
jjg@73 180 }
jjg@73 181 }
jjg@73 182
jjg@73 183 protected char[] initBuf(JavaFileObject fileObject) throws IOException {
jjg@73 184 char[] buf;
jjg@73 185 CharSequence cs = fileObject.getCharContent(true);
jjg@73 186 if (cs instanceof CharBuffer) {
jjg@73 187 CharBuffer cb = (CharBuffer) cs;
jjg@73 188 buf = JavacFileManager.toArray(cb);
jjg@73 189 bufLen = cb.limit();
jjg@73 190 } else {
jjg@73 191 buf = cs.toString().toCharArray();
jjg@73 192 bufLen = buf.length;
jjg@73 193 }
jjg@73 194 refBuf = new SoftReference<char[]>(buf);
jjg@73 195 return buf;
jjg@73 196 }
jjg@73 197
jjg@73 198 /** The underlying file object. */
jjg@73 199 protected JavaFileObject fileObject;
jjg@73 200
ksrini@1138 201 protected EndPosTable endPosTable;
jjg@73 202
jjg@73 203 /** A soft reference to the content of the file object. */
jjg@73 204 protected SoftReference<char[]> refBuf;
jjg@73 205
jjg@73 206 /** A temporary hard reference to the content of the file object. */
jjg@73 207 protected char[] buf;
jjg@73 208
jjg@73 209 /** The length of the content. */
jjg@73 210 protected int bufLen;
jjg@73 211
jjg@73 212 /** The start of a line found by findLine. */
jjg@73 213 protected int lineStart;
jjg@73 214
jjg@73 215 /** The line number of a line found by findLine. */
jjg@73 216 protected int line;
jjg@73 217
jjg@73 218 /** A log for reporting errors, such as errors accessing the content. */
jjg@73 219 protected AbstractLog log;
jjg@73 220 }

mercurial