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