JavacMessager.java revision 2601:8e638f046bf0
1254219Scy/* 2254219Scy * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. 3254219Scy * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4254219Scy * 5254219Scy * This code is free software; you can redistribute it and/or modify it 6254219Scy * under the terms of the GNU General Public License version 2 only, as 7254219Scy * published by the Free Software Foundation. Oracle designates this 8254219Scy * particular file as subject to the "Classpath" exception as provided 9254219Scy * by Oracle in the LICENSE file that accompanied this code. 10254219Scy * 11254219Scy * This code is distributed in the hope that it will be useful, but WITHOUT 12254219Scy * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13254219Scy * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14254219Scy * version 2 for more details (a copy is included in the LICENSE file that 15254219Scy * accompanied this code). 16254219Scy * 17254219Scy * You should have received a copy of the GNU General Public License version 18254219Scy * 2 along with this work; if not, write to the Free Software Foundation, 19254219Scy * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20254219Scy * 21254219Scy * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22254219Scy * or visit www.oracle.com if you need additional information or have any 23254219Scy * questions. 24254219Scy */ 25 26package com.sun.tools.javac.processing; 27 28import com.sun.tools.javac.model.JavacElements; 29import com.sun.tools.javac.util.*; 30import com.sun.tools.javac.util.DefinedBy.Api; 31import com.sun.tools.javac.tree.JCTree; 32import com.sun.tools.javac.tree.JCTree.*; 33import javax.lang.model.element.*; 34import javax.tools.JavaFileObject; 35import javax.tools.Diagnostic; 36import javax.annotation.processing.*; 37 38/** 39 * An implementation of the Messager built on top of log. 40 * 41 * <p><b>This is NOT part of any supported API. 42 * If you write code that depends on this, you do so at your own risk. 43 * This code and its internal interfaces are subject to change or 44 * deletion without notice.</b> 45 */ 46public class JavacMessager implements Messager { 47 Log log; 48 JavacProcessingEnvironment processingEnv; 49 int errorCount = 0; 50 int warningCount = 0; 51 52 JavacMessager(Context context, JavacProcessingEnvironment processingEnv) { 53 log = Log.instance(context); 54 this.processingEnv = processingEnv; 55 } 56 57 // processingEnv.getElementUtils() 58 59 @DefinedBy(Api.ANNOTATION_PROCESSING) 60 public void printMessage(Diagnostic.Kind kind, CharSequence msg) { 61 printMessage(kind, msg, null, null, null); 62 } 63 64 @DefinedBy(Api.ANNOTATION_PROCESSING) 65 public void printMessage(Diagnostic.Kind kind, CharSequence msg, 66 Element e) { 67 printMessage(kind, msg, e, null, null); 68 } 69 70 /** 71 * Prints a message of the specified kind at the location of the 72 * annotation mirror of the annotated element. 73 * 74 * @param kind the kind of message 75 * @param msg the message, or an empty string if none 76 * @param e the annotated element 77 * @param a the annotation to use as a position hint 78 */ 79 @DefinedBy(Api.ANNOTATION_PROCESSING) 80 public void printMessage(Diagnostic.Kind kind, CharSequence msg, 81 Element e, AnnotationMirror a) { 82 printMessage(kind, msg, e, a, null); 83 } 84 85 /** 86 * Prints a message of the specified kind at the location of the 87 * annotation value inside the annotation mirror of the annotated 88 * element. 89 * 90 * @param kind the kind of message 91 * @param msg the message, or an empty string if none 92 * @param e the annotated element 93 * @param a the annotation containing the annotaiton value 94 * @param v the annotation value to use as a position hint 95 */ 96 @DefinedBy(Api.ANNOTATION_PROCESSING) 97 public void printMessage(Diagnostic.Kind kind, CharSequence msg, 98 Element e, AnnotationMirror a, AnnotationValue v) { 99 JavaFileObject oldSource = null; 100 JavaFileObject newSource = null; 101 JCDiagnostic.DiagnosticPosition pos = null; 102 JavacElements elemUtils = processingEnv.getElementUtils(); 103 Pair<JCTree, JCCompilationUnit> treeTop = elemUtils.getTreeAndTopLevel(e, a, v); 104 if (treeTop != null) { 105 newSource = treeTop.snd.sourcefile; 106 if (newSource != null) { 107 // save the old version and reinstate it later 108 oldSource = log.useSource(newSource); 109 pos = treeTop.fst.pos(); 110 } 111 } 112 try { 113 switch (kind) { 114 case ERROR: 115 errorCount++; 116 boolean prev = log.multipleErrors; 117 log.multipleErrors = true; 118 try { 119 log.error(pos, "proc.messager", msg.toString()); 120 } finally { 121 log.multipleErrors = prev; 122 } 123 break; 124 125 case WARNING: 126 warningCount++; 127 log.warning(pos, "proc.messager", msg.toString()); 128 break; 129 130 case MANDATORY_WARNING: 131 warningCount++; 132 log.mandatoryWarning(pos, "proc.messager", msg.toString()); 133 break; 134 135 default: 136 log.note(pos, "proc.messager", msg.toString()); 137 break; 138 } 139 } finally { 140 // reinstate the saved version, only if it was saved earlier 141 if (newSource != null) 142 log.useSource(oldSource); 143 } 144 } 145 146 /** 147 * Prints an error message. 148 * Equivalent to {@code printError(null, msg)}. 149 * @param msg the message, or an empty string if none 150 */ 151 public void printError(String msg) { 152 printMessage(Diagnostic.Kind.ERROR, msg); 153 } 154 155 /** 156 * Prints a warning message. 157 * Equivalent to {@code printWarning(null, msg)}. 158 * @param msg the message, or an empty string if none 159 */ 160 public void printWarning(String msg) { 161 printMessage(Diagnostic.Kind.WARNING, msg); 162 } 163 164 /** 165 * Prints a notice. 166 * @param msg the message, or an empty string if none 167 */ 168 public void printNotice(String msg) { 169 printMessage(Diagnostic.Kind.NOTE, msg); 170 } 171 172 public boolean errorRaised() { 173 return errorCount > 0; 174 } 175 176 public int errorCount() { 177 return errorCount; 178 } 179 180 public int warningCount() { 181 return warningCount; 182 } 183 184 public void newRound() { 185 errorCount = 0; 186 } 187 188 public String toString() { 189 return "javac Messager"; 190 } 191} 192