001 /*
002 * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package com.sun.tools.javac.processing;
027
028 import com.sun.tools.javac.model.JavacElements;
029 import com.sun.tools.javac.util.*;
030 import com.sun.tools.javac.tree.JCTree;
031 import com.sun.tools.javac.tree.JCTree.*;
032 import javax.lang.model.element.*;
033 import javax.tools.JavaFileObject;
034 import javax.tools.Diagnostic;
035 import javax.annotation.processing.*;
036
037 /**
038 * An implementation of the Messager built on top of log.
039 *
040 * <p><b>This is NOT part of any API supported by Sun Microsystems.
041 * If you write code that depends on this, you do so at your own risk.
042 * This code and its internal interfaces are subject to change or
043 * deletion without notice.</b>
044 */
045 public class JavacMessager implements Messager {
046 Log log;
047 JavacProcessingEnvironment processingEnv;
048 int errorCount = 0;
049
050 JavacMessager(Context context, JavacProcessingEnvironment processingEnv) {
051 log = Log.instance(context);
052 this.processingEnv = processingEnv;
053 }
054
055 // processingEnv.getElementUtils()
056
057 public void printMessage(Diagnostic.Kind kind, CharSequence msg) {
058 printMessage(kind, msg, null, null, null);
059 }
060
061 public void printMessage(Diagnostic.Kind kind, CharSequence msg,
062 Element e) {
063 printMessage(kind, msg, e, null, null);
064 }
065
066 /**
067 * Prints a message of the specified kind at the location of the
068 * annotation mirror of the annotated element.
069 *
070 * @param kind the kind of message
071 * @param msg the message, or an empty string if none
072 * @param e the annotated element
073 * @param a the annotation to use as a position hint
074 */
075 public void printMessage(Diagnostic.Kind kind, CharSequence msg,
076 Element e, AnnotationMirror a) {
077 printMessage(kind, msg, e, a, null);
078 }
079
080 /**
081 * Prints a message of the specified kind at the location of the
082 * annotation value inside the annotation mirror of the annotated
083 * element.
084 *
085 * @param kind the kind of message
086 * @param msg the message, or an empty string if none
087 * @param e the annotated element
088 * @param a the annotation containing the annotaiton value
089 * @param v the annotation value to use as a position hint
090 */
091 public void printMessage(Diagnostic.Kind kind, CharSequence msg,
092 Element e, AnnotationMirror a, AnnotationValue v) {
093 JavaFileObject oldSource = null;
094 JavaFileObject newSource = null;
095 JCDiagnostic.DiagnosticPosition pos = null;
096 JavacElements elemUtils = processingEnv.getElementUtils();
097 Pair<JCTree, JCCompilationUnit> treeTop = elemUtils.getTreeAndTopLevel(e, a, v);
098 if (treeTop != null) {
099 newSource = treeTop.snd.sourcefile;
100 if (newSource != null) {
101 oldSource = log.useSource(newSource);
102 pos = treeTop.fst.pos();
103 }
104 }
105 try {
106 switch (kind) {
107 case ERROR:
108 errorCount++;
109 boolean prev = log.multipleErrors;
110 log.multipleErrors = true;
111 try {
112 log.error(pos, "proc.messager", msg.toString());
113 } finally {
114 log.multipleErrors = prev;
115 }
116 break;
117
118 case WARNING:
119 log.warning(pos, "proc.messager", msg.toString());
120 break;
121
122 case MANDATORY_WARNING:
123 log.mandatoryWarning(pos, "proc.messager", msg.toString());
124 break;
125
126 default:
127 log.note(pos, "proc.messager", msg.toString());
128 break;
129 }
130 } finally {
131 if (oldSource != null)
132 log.useSource(oldSource);
133 }
134 }
135
136 /**
137 * Prints an error message.
138 * Equivalent to {@code printError(null, msg)}.
139 * @param msg the message, or an empty string if none
140 */
141 public void printError(String msg) {
142 printMessage(Diagnostic.Kind.ERROR, msg);
143 }
144
145 /**
146 * Prints a warning message.
147 * Equivalent to {@code printWarning(null, msg)}.
148 * @param msg the message, or an empty string if none
149 */
150 public void printWarning(String msg) {
151 printMessage(Diagnostic.Kind.WARNING, msg);
152 }
153
154 /**
155 * Prints a notice.
156 * @param msg the message, or an empty string if none
157 */
158 public void printNotice(String msg) {
159 printMessage(Diagnostic.Kind.NOTE, msg);
160 }
161
162 public boolean errorRaised() {
163 return errorCount > 0;
164 }
165
166 public int errorCount() {
167 return errorCount;
168 }
169
170 public void newRound(Context context) {
171 log = Log.instance(context);
172 errorCount = 0;
173 }
174
175 public String toString() {
176 return "javac Messager";
177 }
178 }