6724071: refactor Log into a front end and back end
authorjjg
Tue, 15 Jul 2008 09:50:36 -0700
changeset 867 1dff24b5f407
parent 865 21668f049d28
child 868 d0f233085cbb
6724071: refactor Log into a front end and back end Reviewed-by: darcy
langtools/src/share/classes/com/sun/tools/javac/util/AbstractLog.java
langtools/src/share/classes/com/sun/tools/javac/util/DiagnosticFormatter.java
langtools/src/share/classes/com/sun/tools/javac/util/DiagnosticSource.java
langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java
langtools/src/share/classes/com/sun/tools/javac/util/Log.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractLog.java	Tue Jul 15 09:50:36 2008 -0700
@@ -0,0 +1,197 @@
+/*
+ * Copyright 1999-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.
+ */
+
+package com.sun.tools.javac.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
+
+
+/**
+ *  A base class for error logs. Reports errors and warnings, and
+ *  keeps track of error numbers and positions.
+ *
+ *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
+ *  you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public abstract class AbstractLog {
+    AbstractLog(JCDiagnostic.Factory diags) {
+        this.diags = diags;
+        sourceMap = new HashMap<JavaFileObject, DiagnosticSource>();
+    }
+
+    /** Re-assign source, returning previous setting.
+     */
+    public JavaFileObject useSource(JavaFileObject file) {
+        JavaFileObject prev = (source == null ? null : source.getFile());
+        source = getSource(file);
+        return prev;
+    }
+
+    protected DiagnosticSource getSource(JavaFileObject file) {
+        if (file == null)
+            return null;
+        DiagnosticSource s = sourceMap.get(file);
+        if (s == null) {
+            s = new DiagnosticSource(file, this);
+            sourceMap.put(file, s);
+        }
+        return s;
+    }
+
+    /** Report an error, unless another error was already reported at same
+     *  source position.
+     *  @param key    The key for the localized error message.
+     *  @param args   Fields of the error message.
+     */
+    public void error(String key, Object ... args) {
+        report(diags.error(source, null, key, args));
+    }
+
+    /** Report an error, unless another error was already reported at same
+     *  source position.
+     *  @param pos    The source position at which to report the error.
+     *  @param key    The key for the localized error message.
+     *  @param args   Fields of the error message.
+     */
+    public void error(DiagnosticPosition pos, String key, Object ... args) {
+        report(diags.error(source, pos, key, args));
+    }
+
+    /** Report an error, unless another error was already reported at same
+     *  source position.
+     *  @param pos    The source position at which to report the error.
+     *  @param key    The key for the localized error message.
+     *  @param args   Fields of the error message.
+     */
+    public void error(int pos, String key, Object ... args) {
+        report(diags.error(source, wrap(pos), key, args));
+    }
+
+    /** Report a warning, unless suppressed by the  -nowarn option or the
+     *  maximum number of warnings has been reached.
+     *  @param pos    The source position at which to report the warning.
+     *  @param key    The key for the localized warning message.
+     *  @param args   Fields of the warning message.
+     */
+    public void warning(String key, Object ... args) {
+        report(diags.warning(source, null, key, args));
+    }
+
+    /** Report a warning, unless suppressed by the  -nowarn option or the
+     *  maximum number of warnings has been reached.
+     *  @param pos    The source position at which to report the warning.
+     *  @param key    The key for the localized warning message.
+     *  @param args   Fields of the warning message.
+     */
+    public void warning(DiagnosticPosition pos, String key, Object ... args) {
+        report(diags.warning(source, pos, key, args));
+    }
+
+    /** Report a warning, unless suppressed by the  -nowarn option or the
+     *  maximum number of warnings has been reached.
+     *  @param pos    The source position at which to report the warning.
+     *  @param key    The key for the localized warning message.
+     *  @param args   Fields of the warning message.
+     */
+    public void warning(int pos, String key, Object ... args) {
+        report(diags.warning(source, wrap(pos), key, args));
+    }
+
+    /** Report a warning.
+     *  @param pos    The source position at which to report the warning.
+     *  @param key    The key for the localized warning message.
+     *  @param args   Fields of the warning message.
+     */
+    public void mandatoryWarning(DiagnosticPosition pos, String key, Object ... args) {
+        report(diags.mandatoryWarning(source, pos, key, args));
+    }
+
+    /** Provide a non-fatal notification, unless suppressed by the -nowarn option.
+     *  @param key    The key for the localized notification message.
+     *  @param args   Fields of the notint an error or warning message:
+     */
+    public void note(String key, Object ... args) {
+        report(diags.note(source, null, key, args));
+    }
+
+    /** Provide a non-fatal notification, unless suppressed by the -nowarn option.
+     *  @param key    The key for the localized notification message.
+     *  @param args   Fields of the notification message.
+     */
+    public void note(DiagnosticPosition pos, String key, Object ... args) {
+        report(diags.note(source, pos, key, args));
+    }
+
+    /** Provide a non-fatal notification, unless suppressed by the -nowarn option.
+     *  @param key    The key for the localized notification message.
+     *  @param args   Fields of the notification message.
+     */
+    public void note(int pos, String key, Object ... args) {
+        report(diags.note(source, wrap(pos), key, args));
+    }
+
+    /** Provide a non-fatal notification, unless suppressed by the -nowarn option.
+     *  @param key    The key for the localized notification message.
+     *  @param args   Fields of the notification message.
+     */
+    public void note(JavaFileObject file, String key, Object ... args) {
+        report(diags.note(getSource(file), null, key, args));
+    }
+
+    /** Provide a non-fatal notification, unless suppressed by the -nowarn option.
+     *  @param key    The key for the localized notification message.
+     *  @param args   Fields of the notification message.
+     */
+    public void mandatoryNote(final JavaFileObject file, String key, Object ... args) {
+        report(diags.mandatoryNote(getSource(file), key, args));
+    }
+
+    protected abstract void report(JCDiagnostic diagnostic);
+
+    protected abstract void directError(String key, Object... args);
+
+    private DiagnosticPosition wrap(int pos) {
+        return (pos == Position.NOPOS ? null : new SimpleDiagnosticPosition(pos));
+    }
+
+    /** Factory for diagnostics
+     */
+    protected JCDiagnostic.Factory diags;
+
+    /** The file that's currently being translated.
+     */
+    protected DiagnosticSource source;
+
+    /** A cache of lightweight DiagnosticSource objects.
+     */
+    protected Map<JavaFileObject, DiagnosticSource> sourceMap;
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/util/DiagnosticFormatter.java	Fri Jul 11 14:59:48 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/DiagnosticFormatter.java	Tue Jul 15 09:50:36 2008 -0700
@@ -28,7 +28,6 @@
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticSource;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
 
 /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/DiagnosticSource.java	Tue Jul 15 09:50:36 2008 -0700
@@ -0,0 +1,214 @@
+/*
+ * Copyright 1999-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.
+ */
+
+package com.sun.tools.javac.util;
+
+import java.io.IOException;
+import java.lang.ref.SoftReference;
+import java.nio.CharBuffer;
+import java.util.Map;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.tree.JCTree;
+
+import static com.sun.tools.javac.util.LayoutCharacters.*;
+
+/**
+ * A simple abstraction of a source file, as needed for use in a diagnostic message.
+ * Provides access to the line and position in a line for any given character offset.
+ *
+ *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
+ *  you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class DiagnosticSource {
+    public DiagnosticSource(JavaFileObject fo, AbstractLog log) {
+        this.fileObject = fo;
+        this.log = log;
+    }
+
+    /** Return the underlying file object handled by this
+     *  DiagnosticSource object.
+     */
+    public JavaFileObject getFile() {
+        return fileObject;
+    }
+
+    public CharSequence getName()  {
+        return JavacFileManager.getJavacBaseFileName(fileObject);
+    }
+
+    /** Return the one-based line number associated with a given pos
+     * for the current source file.  Zero is returned if no line exists
+     * for the given position.
+     */
+    public int getLineNumber(int pos) {
+        try {
+            if (findLine(pos)) {
+                return line;
+            }
+            return 0;
+        } finally {
+            buf = null;
+        }
+    }
+
+    /** Return the one-based column number associated with a given pos
+     * for the current source file.  Zero is returned if no column exists
+     * for the given position.
+     */
+    public int getColumnNumber(int pos) {
+        try {
+            if (findLine(pos)) {
+                int column = 0;
+                for (int bp = lineStart; bp < pos; bp++) {
+                    if (bp >= bufLen) {
+                        return 0;
+                    }
+                    if (buf[bp] == '\t') {
+                        column = (column / TabInc * TabInc) + TabInc;
+                    } else {
+                        column++;
+                    }
+                }
+                return column + 1; // positions are one-based
+            }
+            return 0;
+        } finally {
+            buf = null;
+        }
+    }
+
+    /** Return the content of the line containing a given pos.
+     */
+    public String getLine(int pos) {
+        try {
+            if (!findLine(pos))
+                return null;
+
+            int lineEnd = lineStart;
+            while (lineEnd < bufLen && buf[lineEnd] != CR && buf[lineEnd] != LF)
+                lineEnd++;
+            if (lineEnd - lineStart == 0)
+                return null;
+            return new String(buf, lineStart, lineEnd - lineStart);
+        } finally {
+            buf = null;
+        }
+    }
+
+    public Map<JCTree, Integer> getEndPosTable() {
+        return endPosTable;
+    }
+
+    public void setEndPosTable(Map<JCTree, Integer> t) {
+        if (endPosTable != null && endPosTable != t)
+            throw new IllegalStateException("endPosTable already set");
+        endPosTable = t;
+    }
+
+    /** Find the line in the buffer that contains the current position
+     * @param pos      Character offset into the buffer
+     */
+    private boolean findLine(int pos) {
+        if (pos == Position.NOPOS)
+            return false;
+
+        try {
+            // try and recover buffer from soft reference cache
+            if (buf == null && refBuf != null)
+                buf = refBuf.get();
+
+            if (buf == null) {
+                buf = initBuf(fileObject);
+                lineStart = 0;
+                line = 1;
+            } else if (lineStart > pos) { // messages don't come in order
+                lineStart = 0;
+                line = 1;
+            }
+
+            int bp = lineStart;
+            while (bp < bufLen && bp < pos) {
+                switch (buf[bp++]) {
+                case CR:
+                    if (bp < bufLen && buf[bp] == LF) bp++;
+                    line++;
+                    lineStart = bp;
+                    break;
+                case LF:
+                    line++;
+                    lineStart = bp;
+                    break;
+                }
+            }
+            return bp <= bufLen;
+        } catch (IOException e) {
+            log.directError("source.unavailable");
+            buf = new char[0];
+            return false;
+        }
+    }
+
+    protected char[] initBuf(JavaFileObject fileObject) throws IOException {
+        char[] buf;
+        CharSequence cs = fileObject.getCharContent(true);
+        if (cs instanceof CharBuffer) {
+            CharBuffer cb = (CharBuffer) cs;
+            buf = JavacFileManager.toArray(cb);
+            bufLen = cb.limit();
+        } else {
+            buf = cs.toString().toCharArray();
+            bufLen = buf.length;
+        }
+        refBuf = new SoftReference<char[]>(buf);
+        return buf;
+    }
+
+    /** The underlying file object. */
+    protected JavaFileObject fileObject;
+
+    protected Map<JCTree, Integer> endPosTable;
+
+    /** A soft reference to the content of the file object. */
+    protected SoftReference<char[]> refBuf;
+
+    /** A temporary hard reference to the content of the file object. */
+    protected char[] buf;
+
+    /** The length of the content. */
+    protected int bufLen;
+
+    /** The start of a line found by findLine. */
+    protected int lineStart;
+
+    /** The line number of a line found by findLine. */
+    protected int line;
+
+    /** A log for reporting errors, such as errors accessing the content. */
+    protected AbstractLog log;
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Fri Jul 11 14:59:48 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Tue Jul 15 09:50:36 2008 -0700
@@ -175,18 +175,6 @@
     }
 
     /**
-     * A simple abstraction of a source file, as needed for use in a diagnostic message.
-     */
-    // Note: This class may be superceded by a more general abstraction
-    public interface DiagnosticSource {
-        JavaFileObject getFile();
-        CharSequence getName();
-        int getLineNumber(int pos);
-        int getColumnNumber(int pos);
-        Map<JCTree, Integer> getEndPosTable();
-    };
-
-    /**
      * A DiagnosticType defines the type of the diagnostic.
      **/
     public enum DiagnosticType {
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java	Fri Jul 11 14:59:48 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java	Tue Jul 15 09:50:36 2008 -0700
@@ -26,8 +26,6 @@
 package com.sun.tools.javac.util;
 
 import java.io.*;
-import java.nio.CharBuffer;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
@@ -38,9 +36,6 @@
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
-import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
-
-import static com.sun.tools.javac.util.LayoutCharacters.*;
 
 /** A class for error logs. Reports errors and warnings, and
  *  keeps track of error numbers and positions.
@@ -50,7 +45,7 @@
  *  This code and its internal interfaces are subject to change or
  *  deletion without notice.</b>
  */
-public class Log {
+public class Log extends AbstractLog {
     /** The context key for the log. */
     public static final Context.Key<Log> logKey
         = new Context.Key<Log>();
@@ -98,28 +93,22 @@
      * interface to javac (JSR 199).
      */
     protected DiagnosticListener<? super JavaFileObject> diagListener;
+
     /**
      * Formatter for diagnostics
      */
     private DiagnosticFormatter diagFormatter;
 
-    /**
-     * Factory for diagnostics
-     */
-    private JCDiagnostic.Factory diags;
-
-
     /** Construct a log with given I/O redirections.
      */
     @Deprecated
     protected Log(Context context, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) {
+        super(JCDiagnostic.Factory.instance(context));
         context.put(logKey, this);
         this.errWriter = errWriter;
         this.warnWriter = warnWriter;
         this.noticeWriter = noticeWriter;
 
-        this.diags = JCDiagnostic.Factory.instance(context);
-
         Options options = Options.instance(context);
         this.dumpOnError = options.get("-doe") != null;
         this.promptOnError = options.get("-prompt") != null;
@@ -174,10 +163,6 @@
         return instance;
     }
 
-    /** The file that's currently translated.
-     */
-    protected JCDiagnostic.DiagnosticSource source;
-
     /** The number of errors encountered so far.
      */
     public int nerrors = 0;
@@ -192,77 +177,13 @@
      */
     private Set<Pair<JavaFileObject, Integer>> recorded = new HashSet<Pair<JavaFileObject,Integer>>();
 
-    private Map<JavaFileObject, Map<JCTree, Integer>> endPosTables;
-
-    /** The buffer containing the file that's currently translated.
-     */
-    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;
-
-    /** number of the current source line; first line is 1
-     */
-    private int line;
-
-    /**  buffer index of the first character of the current source line
-     */
-    private int lineStart;
-
     public boolean hasDiagnosticListener() {
         return diagListener != null;
     }
 
     public void setEndPosTable(JavaFileObject name, Map<JCTree, Integer> table) {
-        if (endPosTables == null)
-            endPosTables = new HashMap<JavaFileObject, Map<JCTree, Integer>>();
-        endPosTables.put(name, table);
-    }
-
-    /** Re-assign source, returning previous setting.
-     */
-    public JavaFileObject useSource(final JavaFileObject name) {
-        JavaFileObject prev = currentSource();
-        if (name != prev) {
-            source = new JCDiagnostic.DiagnosticSource() {
-                    public JavaFileObject getFile() {
-                        return name;
-                    }
-                    public CharSequence getName() {
-                        return JavacFileManager.getJavacBaseFileName(getFile());
-                    }
-                    public int getLineNumber(int pos) {
-                        return Log.this.getLineNumber(pos);
-                    }
-                    public int getColumnNumber(int pos) {
-                        return Log.this.getColumnNumber(pos);
-                    }
-                    public Map<JCTree, Integer> getEndPosTable() {
-                        return (endPosTables == null ? null : endPosTables.get(name));
-                    }
-                };
-            buf = null;
-        }
-        return prev;
-    }
-
-    /** Re-assign source buffer for existing source name.
-     */
-    protected void setBuf(char[] newBuf) {
-        buf = newBuf;
-        bufLen = buf.length;
-        bp = 0;
-        lineStart = 0;
-        line = 1;
-    }
-
-    protected char[] getBuf() {
-        return buf;
+        name.getClass(); // null check
+        getSource(name).setEndPosTable(table);
     }
 
     /** Return current source name.
@@ -320,74 +241,19 @@
      *  @param pos   Buffer index of the error position, must be on current line
      */
     private void printErrLine(int pos, PrintWriter writer) {
-        if (!findLine(pos))
+        String line = (source == null ? null : source.getLine(pos));
+        if (line == null)
             return;
+        int col = source.getColumnNumber(pos);
 
-        int lineEnd = lineStart;
-        while (lineEnd < bufLen && buf[lineEnd] != CR && buf[lineEnd] != LF)
-            lineEnd++;
-        if (lineEnd - lineStart == 0)
-            return;
-        printLines(writer, new String(buf, lineStart, lineEnd - lineStart));
-        for (bp = lineStart; bp < pos; bp++) {
-            writer.print((buf[bp] == '\t') ? "\t" : " ");
+        printLines(writer, line);
+        for (int i = 0; i < col - 1; i++) {
+            writer.print((line.charAt(i) == '\t') ? "\t" : " ");
         }
         writer.println("^");
         writer.flush();
     }
 
-    protected void initBuf(JavaFileObject fileObject) throws IOException {
-        CharSequence cs = fileObject.getCharContent(true);
-        if (cs instanceof CharBuffer) {
-            CharBuffer cb = (CharBuffer) cs;
-            buf = JavacFileManager.toArray(cb);
-            bufLen = cb.limit();
-        } else {
-            buf = cs.toString().toCharArray();
-            bufLen = buf.length;
-        }
-    }
-
-    /** Find the line in the buffer that contains the current position
-     * @param pos      Character offset into the buffer
-     */
-    private boolean findLine(int pos) {
-        if (pos == Position.NOPOS || currentSource() == null)
-            return false;
-        try {
-            if (buf == null) {
-                initBuf(currentSource());
-                lineStart = 0;
-                line = 1;
-            } else if (lineStart > pos) { // messages don't come in order
-                lineStart = 0;
-                line = 1;
-            }
-            bp = lineStart;
-            while (bp < bufLen && bp < pos) {
-                switch (buf[bp++]) {
-                case CR:
-                    if (bp < bufLen && buf[bp] == LF) bp++;
-                    line++;
-                    lineStart = bp;
-                    break;
-                case LF:
-                    line++;
-                    lineStart = bp;
-                    break;
-                }
-            }
-            return bp <= bufLen;
-        } catch (IOException e) {
-            //e.printStackTrace();
-            // FIXME: include e.getLocalizedMessage() in error message
-            printLines(errWriter, getLocalizedString("source.unavailable"));
-            errWriter.flush();
-            buf = new char[0];
-        }
-        return false;
-    }
-
     /** Print the text of a message, translating newlines appropriately
      *  for the platform.
      */
@@ -400,72 +266,9 @@
         if (msg.length() != 0) writer.println(msg);
     }
 
-    /** Report an error, unless another error was already reported at same
-     *  source position.
-     *  @param key    The key for the localized error message.
-     *  @param args   Fields of the error message.
-     */
-    public void error(String key, Object ... args) {
-        report(diags.error(source, null, key, args));
-    }
-
-    /** Report an error, unless another error was already reported at same
-     *  source position.
-     *  @param pos    The source position at which to report the error.
-     *  @param key    The key for the localized error message.
-     *  @param args   Fields of the error message.
-     */
-    public void error(DiagnosticPosition pos, String key, Object ... args) {
-        report(diags.error(source, pos, key, args));
-    }
-
-    /** Report an error, unless another error was already reported at same
-     *  source position.
-     *  @param pos    The source position at which to report the error.
-     *  @param key    The key for the localized error message.
-     *  @param args   Fields of the error message.
-     */
-    public void error(int pos, String key, Object ... args) {
-        report(diags.error(source, wrap(pos), key, args));
-    }
-
-    /** Report a warning, unless suppressed by the  -nowarn option or the
-     *  maximum number of warnings has been reached.
-     *  @param pos    The source position at which to report the warning.
-     *  @param key    The key for the localized warning message.
-     *  @param args   Fields of the warning message.
-     */
-    public void warning(String key, Object ... args) {
-        report(diags.warning(source, null, key, args));
-    }
-
-    /** Report a warning, unless suppressed by the  -nowarn option or the
-     *  maximum number of warnings has been reached.
-     *  @param pos    The source position at which to report the warning.
-     *  @param key    The key for the localized warning message.
-     *  @param args   Fields of the warning message.
-     */
-    public void warning(DiagnosticPosition pos, String key, Object ... args) {
-        report(diags.warning(source, pos, key, args));
-    }
-
-    /** Report a warning, unless suppressed by the  -nowarn option or the
-     *  maximum number of warnings has been reached.
-     *  @param pos    The source position at which to report the warning.
-     *  @param key    The key for the localized warning message.
-     *  @param args   Fields of the warning message.
-     */
-    public void warning(int pos, String key, Object ... args) {
-        report(diags.warning(source, wrap(pos), key, args));
-    }
-
-    /** Report a warning.
-     *  @param pos    The source position at which to report the warning.
-     *  @param key    The key for the localized warning message.
-     *  @param args   Fields of the warning message.
-     */
-    public void mandatoryWarning(DiagnosticPosition pos, String key, Object ... args) {
-        report(diags.mandatoryWarning(source, pos, key, args));
+    protected void directError(String key, Object... args) {
+        printLines(errWriter, getLocalizedString(key, args));
+        errWriter.flush();
     }
 
     /** Report a warning that cannot be suppressed.
@@ -478,74 +281,6 @@
         nwarnings++;
     }
 
-    /** Provide a non-fatal notification, unless suppressed by the -nowarn option.
-     *  @param key    The key for the localized notification message.
-     *  @param args   Fields of the notification message.
-     */
-    public void note(String key, Object ... args) {
-        report(diags.note(source, null, key, args));
-    }
-
-    /** Provide a non-fatal notification, unless suppressed by the -nowarn option.
-     *  @param key    The key for the localized notification message.
-     *  @param args   Fields of the notification message.
-     */
-    public void note(DiagnosticPosition pos, String key, Object ... args) {
-        report(diags.note(source, pos, key, args));
-    }
-
-    /** Provide a non-fatal notification, unless suppressed by the -nowarn option.
-     *  @param key    The key for the localized notification message.
-     *  @param args   Fields of the notification message.
-     */
-    public void note(int pos, String key, Object ... args) {
-        report(diags.note(source, wrap(pos), key, args));
-    }
-
-    /** Provide a non-fatal notification, unless suppressed by the -nowarn option.
-     *  @param file   The file to which the note applies.
-     *  @param key    The key for the localized notification message.
-     *  @param args   Fields of the notification message.
-     */
-    public void note(JavaFileObject file, String key, Object ... args) {
-        report(diags.note(wrap(file), null, key, args));
-    }
-
-    /** Provide a non-fatal notification, unless suppressed by the -nowarn option.
-     *  @param key    The key for the localized notification message.
-     *  @param args   Fields of the notification message.
-     */
-    public void mandatoryNote(final JavaFileObject file, String key, Object ... args) {
-        report(diags.mandatoryNote(wrap(file), key, args));
-    }
-
-    private JCDiagnostic.DiagnosticSource wrap(final JavaFileObject file) {
-        if (file == null) {
-            return null;
-        }
-        return new JCDiagnostic.DiagnosticSource() {
-            public JavaFileObject getFile() {
-                return file;
-            }
-            public CharSequence getName() {
-                return JavacFileManager.getJavacBaseFileName(getFile());
-            }
-            public int getLineNumber(int pos) {
-                return Log.this.getLineNumber(pos);
-            }
-            public int getColumnNumber(int pos) {
-                return Log.this.getColumnNumber(pos);
-            }
-            public Map<JCTree, Integer> getEndPosTable() {
-                return (endPosTables == null ? null : endPosTables.get(file));
-            }
-        };
-    }
-
-    private DiagnosticPosition wrap(int pos) {
-        return (pos == Position.NOPOS ? null : new SimpleDiagnosticPosition(pos));
-    }
-
     /**
      * Common diagnostic handling.
      * The diagnostic is counted, and depending on the options and how many diagnostics have been
@@ -657,12 +392,13 @@
  * and quick prototyping
  ***************************************************************************/
 
-/** print an error or warning message:
- */
+    /** print an error or warning message:
+     */
     private void printRawError(int pos, String msg) {
-        if (!findLine(pos)) {
+        if (source == null || pos == Position.NOPOS) {
             printLines(errWriter, "error: " + msg);
         } else {
+            int line = source.getLineNumber(pos);
             JavaFileObject file = currentSource();
             if (file != null)
                 printLines(errWriter,
@@ -673,8 +409,8 @@
         errWriter.flush();
     }
 
-/** report an error:
- */
+    /** report an error:
+     */
     public void rawError(int pos, String msg) {
         if (nerrors < MaxErrors && shouldReport(currentSource(), pos)) {
             printRawError(pos, msg);
@@ -684,8 +420,8 @@
         errWriter.flush();
     }
 
-/** report a warning:
- */
+    /** report a warning:
+     */
     public void rawWarning(int pos, String msg) {
         if (nwarnings < MaxWarnings && emitWarnings) {
             printRawError(pos, "warning: " + msg);
@@ -695,36 +431,6 @@
         errWriter.flush();
     }
 
-    /** Return the one-based line number associated with a given pos
-     * for the current source file.  Zero is returned if no line exists
-     * for the given position.
-     */
-    protected int getLineNumber(int pos) {
-        if (findLine(pos))
-            return line;
-        return 0;
-    }
-
-    /** Return the one-based column number associated with a given pos
-     * for the current source file.  Zero is returned if no column exists
-     * for the given position.
-     */
-    protected int getColumnNumber(int pos) {
-        if (findLine(pos)) {
-            int column = 0;
-            for (bp = lineStart; bp < pos; bp++) {
-                if (bp >= bufLen)
-                    return 0;
-                if (buf[bp] == '\t')
-                    column = (column / TabInc * TabInc) + TabInc;
-                else
-                    column++;
-            }
-            return column + 1; // positions are one-based
-        }
-        return 0;
-    }
-
     public static String format(String fmt, Object... args) {
         return String.format((java.util.Locale)null, fmt, args);
     }