# HG changeset patch # User jjg # Date 1204827904 28800 # Node ID f4b81c733bea47e8e4ccf757c70521fee39ae07e # Parent 9f5e9d551da1df539263fa8b873fdf38369f264b 6668802: javac handles diagnostics for last line badly, if line not terminated by newline Summary: use CharBuffer.limit(), not the length of the backing array Reviewed-by: mcimadamore diff -r 9f5e9d551da1 -r f4b81c733bea langtools/src/share/classes/com/sun/tools/javac/util/Log.java --- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Thu Mar 06 10:07:25 2008 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Thu Mar 06 10:25:04 2008 -0800 @@ -203,6 +203,10 @@ */ private char[] buf = null; + /** The length of useful data in buf + */ + private int bufLen = 0; + /** The position in the buffer at which last error was reported */ private int bp; @@ -256,6 +260,7 @@ */ protected void setBuf(char[] newBuf) { buf = newBuf; + bufLen = buf.length; bp = 0; lineStart = 0; line = 1; @@ -324,7 +329,7 @@ return; int lineEnd = lineStart; - while (lineEnd < buf.length && buf[lineEnd] != CR && buf[lineEnd] != LF) + while (lineEnd < bufLen && buf[lineEnd] != CR && buf[lineEnd] != LF) lineEnd++; if (lineEnd - lineStart == 0) return; @@ -336,12 +341,15 @@ writer.flush(); } - protected static char[] getCharContent(JavaFileObject fileObject) throws IOException { + protected void initBuf(JavaFileObject fileObject) throws IOException { CharSequence cs = fileObject.getCharContent(true); if (cs instanceof CharBuffer) { - return JavacFileManager.toArray((CharBuffer)cs); + CharBuffer cb = (CharBuffer) cs; + buf = JavacFileManager.toArray(cb); + bufLen = cb.limit(); } else { - return cs.toString().toCharArray(); + buf = cs.toString().toCharArray(); + bufLen = buf.length; } } @@ -353,7 +361,7 @@ return false; try { if (buf == null) { - buf = getCharContent(currentSource()); + initBuf(currentSource()); lineStart = 0; line = 1; } else if (lineStart > pos) { // messages don't come in order @@ -361,10 +369,10 @@ line = 1; } bp = lineStart; - while (bp < buf.length && bp < pos) { + while (bp < bufLen && bp < pos) { switch (buf[bp++]) { case CR: - if (bp < buf.length && buf[bp] == LF) bp++; + if (bp < bufLen && buf[bp] == LF) bp++; line++; lineStart = bp; break; @@ -374,7 +382,7 @@ break; } } - return bp <= buf.length; + return bp <= bufLen; } catch (IOException e) { //e.printStackTrace(); // FIXME: include e.getLocalizedMessage() in error message @@ -704,7 +712,7 @@ if (findLine(pos)) { int column = 0; for (bp = lineStart; bp < pos; bp++) { - if (bp >= buf.length) + if (bp >= bufLen) return 0; if (buf[bp] == '\t') column = (column / TabInc * TabInc) + TabInc; diff -r 9f5e9d551da1 -r f4b81c733bea langtools/test/tools/javac/T6668802.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/T6668802.java Thu Mar 06 10:25:04 2008 -0800 @@ -0,0 +1,79 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6668802 + * @summary javac handles diagnostics for last line badly, if line not terminated by newline + */ + +import java.io.*; +import java.util.*; + +public class T6668802 +{ + public static void main(String[] args) throws Exception { + new T6668802().run(); + } + + void run() throws Exception { + String test = "public class Test {"; + File f = writeTestFile("Test.java", test); + String[] out = compileBadFile(f); + for (String line: out) + System.err.println(">>>" + line + "<<<"); + if (!out[1].equals(test)) { + show("expected", test); + show(" actual", out[1]); + throw new Error("test failed"); + } + } + + File writeTestFile(String path, String contents) throws IOException { + File f = new File(path); + FileWriter out = new FileWriter(f); + out.write(contents); + out.close(); + return f; + } + + String[] compileBadFile(File file) throws IOException { + List options = new ArrayList(); + options.add(file.getPath()); + System.err.println("compile: " + options); + String[] opts = options.toArray(new String[options.size()]); + StringWriter sw = new StringWriter(); + PrintWriter out = new PrintWriter(sw); + int rc = com.sun.tools.javac.Main.compile(opts, out); + if (rc == 0) + throw new Error("compilation succeeded unexpectedly"); + out.close(); + return sw.toString().split("[\n\r]+"); + } + + void show(String prefix, String text) { + System.err.println(prefix + ": (" + text.length() + ") " + text); + } +}