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 26 package com.sun.tools.javac.processing; 27 28 import com.sun.tools.javac.model.JavacElements; 29 import com.sun.tools.javac.resources.CompilerProperties.Errors; 30 import com.sun.tools.javac.resources.CompilerProperties.Notes; 31 import com.sun.tools.javac.resources.CompilerProperties.Warnings; 32 import com.sun.tools.javac.util.*; 33 import com.sun.tools.javac.util.DefinedBy.Api; 34 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; 35 import com.sun.tools.javac.tree.JCTree; 36 import com.sun.tools.javac.tree.JCTree.*; 37 import java.util.Set; 38 import javax.lang.model.element.*; 39 import javax.tools.JavaFileObject; 40 import javax.tools.Diagnostic; 41 import javax.annotation.processing.*; 42 43 /** 44 * An implementation of the Messager built on top of log. 45 * 46 * <p><b>This is NOT part of any supported API. 47 * If you write code that depends on this, you do so at your own risk. 48 * This code and its internal interfaces are subject to change or 49 * deletion without notice.</b> 50 */ 51 public class JavacMessager implements Messager { 52 Log log; 53 JavacProcessingEnvironment processingEnv; 54 int errorCount = 0; 55 int warningCount = 0; 56 57 JavacMessager(Context context, JavacProcessingEnvironment processingEnv) { 58 log = Log.instance(context); 59 this.processingEnv = processingEnv; 60 } 61 62 // processingEnv.getElementUtils() 63 64 @DefinedBy(Api.ANNOTATION_PROCESSING) 65 public void printMessage(Diagnostic.Kind kind, CharSequence msg) { 66 printMessage(kind, msg, null, null, null); 67 } 68 69 @DefinedBy(Api.ANNOTATION_PROCESSING) 70 public void printMessage(Diagnostic.Kind kind, CharSequence msg, 71 Element e) { 72 printMessage(kind, msg, e, null, null); 73 } 74 75 /** 76 * Prints a message of the specified kind at the location of the 77 * annotation mirror of the annotated element. 78 * 79 * @param kind the kind of message 80 * @param msg the message, or an empty string if none 81 * @param e the annotated element 82 * @param a the annotation to use as a position hint 83 */ 84 @DefinedBy(Api.ANNOTATION_PROCESSING) 85 public void printMessage(Diagnostic.Kind kind, CharSequence msg, 86 Element e, AnnotationMirror a) { 87 printMessage(kind, msg, e, a, null); 88 } 89 90 /** 91 * Prints a message of the specified kind at the location of the 92 * annotation value inside the annotation mirror of the annotated 93 * element. 94 * 95 * @param kind the kind of message 96 * @param msg the message, or an empty string if none 97 * @param e the annotated element 98 * @param a the annotation containing the annotation value 99 * @param v the annotation value to use as a position hint 100 */ 101 @DefinedBy(Api.ANNOTATION_PROCESSING) 102 public void printMessage(Diagnostic.Kind kind, CharSequence msg, 103 Element e, AnnotationMirror a, AnnotationValue v) { 104 JavaFileObject oldSource = null; 105 JavaFileObject newSource = null; 106 JCDiagnostic.DiagnosticPosition pos = null; 107 JavacElements elemUtils = processingEnv.getElementUtils(); 108 Pair<JCTree, JCCompilationUnit> treeTop = elemUtils.getTreeAndTopLevel(e, a, v); 109 if (treeTop != null) { 110 newSource = treeTop.snd.sourcefile; 111 if (newSource != null) { 112 // save the old version and reinstate it later 113 oldSource = log.useSource(newSource); 114 pos = treeTop.fst.pos(); 115 } 116 } 117 try { 118 switch (kind) { 119 case ERROR: 120 errorCount++; 121 log.error(DiagnosticFlag.API, pos, Errors.ProcMessager(msg.toString())); 122 break; 123 124 case WARNING: 125 warningCount++; 126 log.warning(pos, Warnings.ProcMessager(msg.toString())); 127 break; 128 129 case MANDATORY_WARNING: 130 warningCount++; 131 log.mandatoryWarning(pos, Warnings.ProcMessager(msg.toString())); 132 break; 133 134 default: 135 log.note(pos, Notes.ProcMessager(msg.toString())); 136 break; 137 } 138 } finally { 139 // reinstate the saved version, only if it was saved earlier 140 if (newSource != null) 141 log.useSource(oldSource); 142 } 143 } 144 145 /** 146 * Prints an error message. 147 * Equivalent to {@code printError(null, msg)}. 148 * @param msg the message, or an empty string if none 149 */ 150 public void printError(String msg) { 151 printMessage(Diagnostic.Kind.ERROR, msg); 152 } 153 154 /** 155 * Prints a warning message. 156 * Equivalent to {@code printWarning(null, msg)}. 157 * @param msg the message, or an empty string if none 158 */ 159 public void printWarning(String msg) { 160 printMessage(Diagnostic.Kind.WARNING, msg); 161 } 162 163 /** 164 * Prints a notice. 165 * @param msg the message, or an empty string if none 166 */ 167 public void printNotice(String msg) { 168 printMessage(Diagnostic.Kind.NOTE, msg); 169 } 170 171 public boolean errorRaised() { 172 return errorCount > 0; 173 } 174 175 public int errorCount() { 176 return errorCount; 177 } 178 179 public int warningCount() { 180 return warningCount; 181 } 182 183 public void newRound() { 184 errorCount = 0; 185 } 186 187 public String toString() { 188 return "javac Messager"; 189 } 190 }