src/share/classes/com/sun/tools/javac/api/JavacTrees.java

Wed, 27 Apr 2016 01:34:52 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:34:52 +0800
changeset 0
959103a6100f
child 2525
2eb010b6cb22
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.tools.javac.api;
aoqi@0 27
aoqi@0 28 import java.io.IOException;
aoqi@0 29 import java.util.HashSet;
aoqi@0 30 import java.util.Set;
aoqi@0 31
aoqi@0 32 import javax.annotation.processing.ProcessingEnvironment;
aoqi@0 33 import javax.lang.model.element.AnnotationMirror;
aoqi@0 34 import javax.lang.model.element.AnnotationValue;
aoqi@0 35 import javax.lang.model.element.Element;
aoqi@0 36 import javax.lang.model.element.ElementKind;
aoqi@0 37 import javax.lang.model.element.ExecutableElement;
aoqi@0 38 import javax.lang.model.element.TypeElement;
aoqi@0 39 import javax.lang.model.type.DeclaredType;
aoqi@0 40 import javax.lang.model.type.TypeKind;
aoqi@0 41 import javax.lang.model.type.TypeMirror;
aoqi@0 42 import javax.tools.Diagnostic;
aoqi@0 43 import javax.tools.JavaCompiler;
aoqi@0 44 import javax.tools.JavaFileObject;
aoqi@0 45
aoqi@0 46 import com.sun.source.doctree.DocCommentTree;
aoqi@0 47 import com.sun.source.doctree.DocTree;
aoqi@0 48 import com.sun.source.tree.CatchTree;
aoqi@0 49 import com.sun.source.tree.CompilationUnitTree;
aoqi@0 50 import com.sun.source.tree.Scope;
aoqi@0 51 import com.sun.source.tree.Tree;
aoqi@0 52 import com.sun.source.util.DocSourcePositions;
aoqi@0 53 import com.sun.source.util.DocTreePath;
aoqi@0 54 import com.sun.source.util.DocTreeScanner;
aoqi@0 55 import com.sun.source.util.DocTrees;
aoqi@0 56 import com.sun.source.util.JavacTask;
aoqi@0 57 import com.sun.source.util.TreePath;
aoqi@0 58 import com.sun.tools.javac.code.Flags;
aoqi@0 59 import com.sun.tools.javac.code.Kinds;
aoqi@0 60 import com.sun.tools.javac.code.Symbol;
aoqi@0 61 import com.sun.tools.javac.code.Symbol.ClassSymbol;
aoqi@0 62 import com.sun.tools.javac.code.Symbol.MethodSymbol;
aoqi@0 63 import com.sun.tools.javac.code.Symbol.PackageSymbol;
aoqi@0 64 import com.sun.tools.javac.code.Symbol.TypeSymbol;
aoqi@0 65 import com.sun.tools.javac.code.Symbol.VarSymbol;
aoqi@0 66 import com.sun.tools.javac.code.Type;
aoqi@0 67 import com.sun.tools.javac.code.Type.ArrayType;
aoqi@0 68 import com.sun.tools.javac.code.Type.ClassType;
aoqi@0 69 import com.sun.tools.javac.code.Type.ErrorType;
aoqi@0 70 import com.sun.tools.javac.code.Type.UnionClassType;
aoqi@0 71 import com.sun.tools.javac.code.Types;
aoqi@0 72 import com.sun.tools.javac.code.Types.TypeRelation;
aoqi@0 73 import com.sun.tools.javac.comp.Attr;
aoqi@0 74 import com.sun.tools.javac.comp.AttrContext;
aoqi@0 75 import com.sun.tools.javac.comp.Enter;
aoqi@0 76 import com.sun.tools.javac.comp.Env;
aoqi@0 77 import com.sun.tools.javac.comp.MemberEnter;
aoqi@0 78 import com.sun.tools.javac.comp.Resolve;
aoqi@0 79 import com.sun.tools.javac.model.JavacElements;
aoqi@0 80 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
aoqi@0 81 import com.sun.tools.javac.tree.DCTree;
aoqi@0 82 import com.sun.tools.javac.tree.DCTree.DCBlockTag;
aoqi@0 83 import com.sun.tools.javac.tree.DCTree.DCDocComment;
aoqi@0 84 import com.sun.tools.javac.tree.DCTree.DCEndPosTree;
aoqi@0 85 import com.sun.tools.javac.tree.DCTree.DCErroneous;
aoqi@0 86 import com.sun.tools.javac.tree.DCTree.DCIdentifier;
aoqi@0 87 import com.sun.tools.javac.tree.DCTree.DCParam;
aoqi@0 88 import com.sun.tools.javac.tree.DCTree.DCReference;
aoqi@0 89 import com.sun.tools.javac.tree.DCTree.DCText;
aoqi@0 90 import com.sun.tools.javac.tree.EndPosTable;
aoqi@0 91 import com.sun.tools.javac.tree.JCTree;
aoqi@0 92 import com.sun.tools.javac.tree.JCTree.*;
aoqi@0 93 import com.sun.tools.javac.tree.TreeCopier;
aoqi@0 94 import com.sun.tools.javac.tree.TreeInfo;
aoqi@0 95 import com.sun.tools.javac.tree.TreeMaker;
aoqi@0 96 import com.sun.tools.javac.util.Abort;
aoqi@0 97 import com.sun.tools.javac.util.Assert;
aoqi@0 98 import com.sun.tools.javac.util.Context;
aoqi@0 99 import com.sun.tools.javac.util.JCDiagnostic;
aoqi@0 100 import com.sun.tools.javac.util.List;
aoqi@0 101 import com.sun.tools.javac.util.ListBuffer;
aoqi@0 102 import com.sun.tools.javac.util.Log;
aoqi@0 103 import com.sun.tools.javac.util.Name;
aoqi@0 104 import com.sun.tools.javac.util.Names;
aoqi@0 105 import com.sun.tools.javac.util.Pair;
aoqi@0 106 import com.sun.tools.javac.util.Position;
aoqi@0 107 import static com.sun.tools.javac.code.TypeTag.*;
aoqi@0 108
aoqi@0 109 /**
aoqi@0 110 * Provides an implementation of Trees.
aoqi@0 111 *
aoqi@0 112 * <p><b>This is NOT part of any supported API.
aoqi@0 113 * If you write code that depends on this, you do so at your own
aoqi@0 114 * risk. This code and its internal interfaces are subject to change
aoqi@0 115 * or deletion without notice.</b></p>
aoqi@0 116 *
aoqi@0 117 * @author Peter von der Ah&eacute;
aoqi@0 118 */
aoqi@0 119 public class JavacTrees extends DocTrees {
aoqi@0 120
aoqi@0 121 // in a world of a single context per compilation, these would all be final
aoqi@0 122 private Resolve resolve;
aoqi@0 123 private Enter enter;
aoqi@0 124 private Log log;
aoqi@0 125 private MemberEnter memberEnter;
aoqi@0 126 private Attr attr;
aoqi@0 127 private TreeMaker treeMaker;
aoqi@0 128 private JavacElements elements;
aoqi@0 129 private JavacTaskImpl javacTaskImpl;
aoqi@0 130 private Names names;
aoqi@0 131 private Types types;
aoqi@0 132
aoqi@0 133 // called reflectively from Trees.instance(CompilationTask task)
aoqi@0 134 public static JavacTrees instance(JavaCompiler.CompilationTask task) {
aoqi@0 135 if (!(task instanceof BasicJavacTask))
aoqi@0 136 throw new IllegalArgumentException();
aoqi@0 137 return instance(((BasicJavacTask)task).getContext());
aoqi@0 138 }
aoqi@0 139
aoqi@0 140 // called reflectively from Trees.instance(ProcessingEnvironment env)
aoqi@0 141 public static JavacTrees instance(ProcessingEnvironment env) {
aoqi@0 142 if (!(env instanceof JavacProcessingEnvironment))
aoqi@0 143 throw new IllegalArgumentException();
aoqi@0 144 return instance(((JavacProcessingEnvironment)env).getContext());
aoqi@0 145 }
aoqi@0 146
aoqi@0 147 public static JavacTrees instance(Context context) {
aoqi@0 148 JavacTrees instance = context.get(JavacTrees.class);
aoqi@0 149 if (instance == null)
aoqi@0 150 instance = new JavacTrees(context);
aoqi@0 151 return instance;
aoqi@0 152 }
aoqi@0 153
aoqi@0 154 protected JavacTrees(Context context) {
aoqi@0 155 context.put(JavacTrees.class, this);
aoqi@0 156 init(context);
aoqi@0 157 }
aoqi@0 158
aoqi@0 159 public void updateContext(Context context) {
aoqi@0 160 init(context);
aoqi@0 161 }
aoqi@0 162
aoqi@0 163 private void init(Context context) {
aoqi@0 164 attr = Attr.instance(context);
aoqi@0 165 enter = Enter.instance(context);
aoqi@0 166 elements = JavacElements.instance(context);
aoqi@0 167 log = Log.instance(context);
aoqi@0 168 resolve = Resolve.instance(context);
aoqi@0 169 treeMaker = TreeMaker.instance(context);
aoqi@0 170 memberEnter = MemberEnter.instance(context);
aoqi@0 171 names = Names.instance(context);
aoqi@0 172 types = Types.instance(context);
aoqi@0 173
aoqi@0 174 JavacTask t = context.get(JavacTask.class);
aoqi@0 175 if (t instanceof JavacTaskImpl)
aoqi@0 176 javacTaskImpl = (JavacTaskImpl) t;
aoqi@0 177 }
aoqi@0 178
aoqi@0 179 public DocSourcePositions getSourcePositions() {
aoqi@0 180 return new DocSourcePositions() {
aoqi@0 181 public long getStartPosition(CompilationUnitTree file, Tree tree) {
aoqi@0 182 return TreeInfo.getStartPos((JCTree) tree);
aoqi@0 183 }
aoqi@0 184
aoqi@0 185 public long getEndPosition(CompilationUnitTree file, Tree tree) {
aoqi@0 186 EndPosTable endPosTable = ((JCCompilationUnit) file).endPositions;
aoqi@0 187 return TreeInfo.getEndPos((JCTree) tree, endPosTable);
aoqi@0 188 }
aoqi@0 189
aoqi@0 190 public long getStartPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree) {
aoqi@0 191 return ((DCTree) tree).getSourcePosition((DCDocComment) comment);
aoqi@0 192 }
aoqi@0 193 @SuppressWarnings("fallthrough")
aoqi@0 194 public long getEndPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree) {
aoqi@0 195 DCDocComment dcComment = (DCDocComment) comment;
aoqi@0 196 if (tree instanceof DCEndPosTree) {
aoqi@0 197 int endPos = ((DCEndPosTree) tree).getEndPos(dcComment);
aoqi@0 198
aoqi@0 199 if (endPos != Position.NOPOS) {
aoqi@0 200 return endPos;
aoqi@0 201 }
aoqi@0 202 }
aoqi@0 203 int correction = 0;
aoqi@0 204 switch (tree.getKind()) {
aoqi@0 205 case TEXT:
aoqi@0 206 DCText text = (DCText) tree;
aoqi@0 207
aoqi@0 208 return dcComment.comment.getSourcePos(text.pos + text.text.length());
aoqi@0 209 case ERRONEOUS:
aoqi@0 210 DCErroneous err = (DCErroneous) tree;
aoqi@0 211
aoqi@0 212 return dcComment.comment.getSourcePos(err.pos + err.body.length());
aoqi@0 213 case IDENTIFIER:
aoqi@0 214 DCIdentifier ident = (DCIdentifier) tree;
aoqi@0 215
aoqi@0 216 return dcComment.comment.getSourcePos(ident.pos + (ident.name != names.error ? ident.name.length() : 0));
aoqi@0 217 case PARAM:
aoqi@0 218 DCParam param = (DCParam) tree;
aoqi@0 219
aoqi@0 220 if (param.isTypeParameter && param.getDescription().isEmpty()) {
aoqi@0 221 correction = 1;
aoqi@0 222 }
aoqi@0 223 case AUTHOR: case DEPRECATED: case RETURN: case SEE:
aoqi@0 224 case SERIAL: case SERIAL_DATA: case SERIAL_FIELD: case SINCE:
aoqi@0 225 case THROWS: case UNKNOWN_BLOCK_TAG: case VERSION: {
aoqi@0 226 DocTree last = getLastChild(tree);
aoqi@0 227
aoqi@0 228 if (last != null) {
aoqi@0 229 return getEndPosition(file, comment, last) + correction;
aoqi@0 230 }
aoqi@0 231
aoqi@0 232 DCBlockTag block = (DCBlockTag) tree;
aoqi@0 233
aoqi@0 234 return dcComment.comment.getSourcePos(block.pos + block.getTagName().length() + 1);
aoqi@0 235 }
aoqi@0 236 default:
aoqi@0 237 DocTree last = getLastChild(tree);
aoqi@0 238
aoqi@0 239 if (last != null) {
aoqi@0 240 return getEndPosition(file, comment, last);
aoqi@0 241 }
aoqi@0 242 break;
aoqi@0 243 }
aoqi@0 244
aoqi@0 245 return Position.NOPOS;
aoqi@0 246 }
aoqi@0 247 };
aoqi@0 248 }
aoqi@0 249
aoqi@0 250 private DocTree getLastChild(DocTree tree) {
aoqi@0 251 final DocTree[] last = new DocTree[] {null};
aoqi@0 252
aoqi@0 253 tree.accept(new DocTreeScanner<Void, Void>() {
aoqi@0 254 @Override public Void scan(DocTree node, Void p) {
aoqi@0 255 if (node != null) last[0] = node;
aoqi@0 256 return null;
aoqi@0 257 }
aoqi@0 258 }, null);
aoqi@0 259
aoqi@0 260 return last[0];
aoqi@0 261 }
aoqi@0 262
aoqi@0 263 public JCClassDecl getTree(TypeElement element) {
aoqi@0 264 return (JCClassDecl) getTree((Element) element);
aoqi@0 265 }
aoqi@0 266
aoqi@0 267 public JCMethodDecl getTree(ExecutableElement method) {
aoqi@0 268 return (JCMethodDecl) getTree((Element) method);
aoqi@0 269 }
aoqi@0 270
aoqi@0 271 public JCTree getTree(Element element) {
aoqi@0 272 Symbol symbol = (Symbol) element;
aoqi@0 273 TypeSymbol enclosing = symbol.enclClass();
aoqi@0 274 Env<AttrContext> env = enter.getEnv(enclosing);
aoqi@0 275 if (env == null)
aoqi@0 276 return null;
aoqi@0 277 JCClassDecl classNode = env.enclClass;
aoqi@0 278 if (classNode != null) {
aoqi@0 279 if (TreeInfo.symbolFor(classNode) == element)
aoqi@0 280 return classNode;
aoqi@0 281 for (JCTree node : classNode.getMembers())
aoqi@0 282 if (TreeInfo.symbolFor(node) == element)
aoqi@0 283 return node;
aoqi@0 284 }
aoqi@0 285 return null;
aoqi@0 286 }
aoqi@0 287
aoqi@0 288 public JCTree getTree(Element e, AnnotationMirror a) {
aoqi@0 289 return getTree(e, a, null);
aoqi@0 290 }
aoqi@0 291
aoqi@0 292 public JCTree getTree(Element e, AnnotationMirror a, AnnotationValue v) {
aoqi@0 293 Pair<JCTree, JCCompilationUnit> treeTopLevel = elements.getTreeAndTopLevel(e, a, v);
aoqi@0 294 if (treeTopLevel == null)
aoqi@0 295 return null;
aoqi@0 296 return treeTopLevel.fst;
aoqi@0 297 }
aoqi@0 298
aoqi@0 299 public TreePath getPath(CompilationUnitTree unit, Tree node) {
aoqi@0 300 return TreePath.getPath(unit, node);
aoqi@0 301 }
aoqi@0 302
aoqi@0 303 public TreePath getPath(Element e) {
aoqi@0 304 return getPath(e, null, null);
aoqi@0 305 }
aoqi@0 306
aoqi@0 307 public TreePath getPath(Element e, AnnotationMirror a) {
aoqi@0 308 return getPath(e, a, null);
aoqi@0 309 }
aoqi@0 310
aoqi@0 311 public TreePath getPath(Element e, AnnotationMirror a, AnnotationValue v) {
aoqi@0 312 final Pair<JCTree, JCCompilationUnit> treeTopLevel = elements.getTreeAndTopLevel(e, a, v);
aoqi@0 313 if (treeTopLevel == null)
aoqi@0 314 return null;
aoqi@0 315 return TreePath.getPath(treeTopLevel.snd, treeTopLevel.fst);
aoqi@0 316 }
aoqi@0 317
aoqi@0 318 public Symbol getElement(TreePath path) {
aoqi@0 319 JCTree tree = (JCTree) path.getLeaf();
aoqi@0 320 Symbol sym = TreeInfo.symbolFor(tree);
aoqi@0 321 if (sym == null) {
aoqi@0 322 if (TreeInfo.isDeclaration(tree)) {
aoqi@0 323 for (TreePath p = path; p != null; p = p.getParentPath()) {
aoqi@0 324 JCTree t = (JCTree) p.getLeaf();
aoqi@0 325 if (t.hasTag(JCTree.Tag.CLASSDEF)) {
aoqi@0 326 JCClassDecl ct = (JCClassDecl) t;
aoqi@0 327 if (ct.sym != null) {
aoqi@0 328 if ((ct.sym.flags_field & Flags.UNATTRIBUTED) != 0) {
aoqi@0 329 attr.attribClass(ct.pos(), ct.sym);
aoqi@0 330 sym = TreeInfo.symbolFor(tree);
aoqi@0 331 }
aoqi@0 332 break;
aoqi@0 333 }
aoqi@0 334 }
aoqi@0 335 }
aoqi@0 336 }
aoqi@0 337 }
aoqi@0 338 return sym;
aoqi@0 339 }
aoqi@0 340
aoqi@0 341 @Override
aoqi@0 342 public Element getElement(DocTreePath path) {
aoqi@0 343 DocTree forTree = path.getLeaf();
aoqi@0 344 if (forTree instanceof DCReference)
aoqi@0 345 return attributeDocReference(path.getTreePath(), ((DCReference) forTree));
aoqi@0 346 if (forTree instanceof DCIdentifier) {
aoqi@0 347 if (path.getParentPath().getLeaf() instanceof DCParam) {
aoqi@0 348 return attributeParamIdentifier(path.getTreePath(), (DCParam) path.getParentPath().getLeaf());
aoqi@0 349 }
aoqi@0 350 }
aoqi@0 351 return null;
aoqi@0 352 }
aoqi@0 353
aoqi@0 354 private Symbol attributeDocReference(TreePath path, DCReference ref) {
aoqi@0 355 Env<AttrContext> env = getAttrContext(path);
aoqi@0 356
aoqi@0 357 Log.DeferredDiagnosticHandler deferredDiagnosticHandler =
aoqi@0 358 new Log.DeferredDiagnosticHandler(log);
aoqi@0 359 try {
aoqi@0 360 final TypeSymbol tsym;
aoqi@0 361 final Name memberName;
aoqi@0 362 if (ref.qualifierExpression == null) {
aoqi@0 363 tsym = env.enclClass.sym;
aoqi@0 364 memberName = ref.memberName;
aoqi@0 365 } else {
aoqi@0 366 // See if the qualifierExpression is a type or package name.
aoqi@0 367 // javac does not provide the exact method required, so
aoqi@0 368 // we first check if qualifierExpression identifies a type,
aoqi@0 369 // and if not, then we check to see if it identifies a package.
aoqi@0 370 Type t = attr.attribType(ref.qualifierExpression, env);
aoqi@0 371 if (t.isErroneous()) {
aoqi@0 372 if (ref.memberName == null) {
aoqi@0 373 // Attr/Resolve assume packages exist and create symbols as needed
aoqi@0 374 // so use getPackageElement to restrict search to existing packages
aoqi@0 375 PackageSymbol pck = elements.getPackageElement(ref.qualifierExpression.toString());
aoqi@0 376 if (pck != null) {
aoqi@0 377 return pck;
aoqi@0 378 } else if (ref.qualifierExpression.hasTag(JCTree.Tag.IDENT)) {
aoqi@0 379 // fixup: allow "identifier" instead of "#identifier"
aoqi@0 380 // for compatibility with javadoc
aoqi@0 381 tsym = env.enclClass.sym;
aoqi@0 382 memberName = ((JCIdent) ref.qualifierExpression).name;
aoqi@0 383 } else
aoqi@0 384 return null;
aoqi@0 385 } else {
aoqi@0 386 return null;
aoqi@0 387 }
aoqi@0 388 } else {
aoqi@0 389 tsym = t.tsym;
aoqi@0 390 memberName = ref.memberName;
aoqi@0 391 }
aoqi@0 392 }
aoqi@0 393
aoqi@0 394 if (memberName == null)
aoqi@0 395 return tsym;
aoqi@0 396
aoqi@0 397 final List<Type> paramTypes;
aoqi@0 398 if (ref.paramTypes == null)
aoqi@0 399 paramTypes = null;
aoqi@0 400 else {
aoqi@0 401 ListBuffer<Type> lb = new ListBuffer<Type>();
aoqi@0 402 for (List<JCTree> l = ref.paramTypes; l.nonEmpty(); l = l.tail) {
aoqi@0 403 JCTree tree = l.head;
aoqi@0 404 Type t = attr.attribType(tree, env);
aoqi@0 405 lb.add(t);
aoqi@0 406 }
aoqi@0 407 paramTypes = lb.toList();
aoqi@0 408 }
aoqi@0 409
aoqi@0 410 ClassSymbol sym = (ClassSymbol) types.cvarUpperBound(tsym.type).tsym;
aoqi@0 411
aoqi@0 412 Symbol msym = (memberName == sym.name)
aoqi@0 413 ? findConstructor(sym, paramTypes)
aoqi@0 414 : findMethod(sym, memberName, paramTypes);
aoqi@0 415 if (paramTypes != null) {
aoqi@0 416 // explicit (possibly empty) arg list given, so cannot be a field
aoqi@0 417 return msym;
aoqi@0 418 }
aoqi@0 419
aoqi@0 420 VarSymbol vsym = (ref.paramTypes != null) ? null : findField(sym, memberName);
aoqi@0 421 // prefer a field over a method with no parameters
aoqi@0 422 if (vsym != null &&
aoqi@0 423 (msym == null ||
aoqi@0 424 types.isSubtypeUnchecked(vsym.enclClass().asType(), msym.enclClass().asType()))) {
aoqi@0 425 return vsym;
aoqi@0 426 } else {
aoqi@0 427 return msym;
aoqi@0 428 }
aoqi@0 429 } catch (Abort e) { // may be thrown by Check.completionError in case of bad class file
aoqi@0 430 return null;
aoqi@0 431 } finally {
aoqi@0 432 log.popDiagnosticHandler(deferredDiagnosticHandler);
aoqi@0 433 }
aoqi@0 434 }
aoqi@0 435
aoqi@0 436 private Symbol attributeParamIdentifier(TreePath path, DCParam ptag) {
aoqi@0 437 Symbol javadocSymbol = getElement(path);
aoqi@0 438 if (javadocSymbol == null)
aoqi@0 439 return null;
aoqi@0 440 ElementKind kind = javadocSymbol.getKind();
aoqi@0 441 List<? extends Symbol> params = List.nil();
aoqi@0 442 if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) {
aoqi@0 443 MethodSymbol ee = (MethodSymbol) javadocSymbol;
aoqi@0 444 params = ptag.isTypeParameter()
aoqi@0 445 ? ee.getTypeParameters()
aoqi@0 446 : ee.getParameters();
aoqi@0 447 } else if (kind.isClass() || kind.isInterface()) {
aoqi@0 448 ClassSymbol te = (ClassSymbol) javadocSymbol;
aoqi@0 449 params = te.getTypeParameters();
aoqi@0 450 }
aoqi@0 451
aoqi@0 452 for (Symbol param : params) {
aoqi@0 453 if (param.getSimpleName() == ptag.getName().getName()) {
aoqi@0 454 return param;
aoqi@0 455 }
aoqi@0 456 }
aoqi@0 457 return null;
aoqi@0 458 }
aoqi@0 459
aoqi@0 460 /** @see com.sun.tools.javadoc.ClassDocImpl#findField */
aoqi@0 461 private VarSymbol findField(ClassSymbol tsym, Name fieldName) {
aoqi@0 462 return searchField(tsym, fieldName, new HashSet<ClassSymbol>());
aoqi@0 463 }
aoqi@0 464
aoqi@0 465 /** @see com.sun.tools.javadoc.ClassDocImpl#searchField */
aoqi@0 466 private VarSymbol searchField(ClassSymbol tsym, Name fieldName, Set<ClassSymbol> searched) {
aoqi@0 467 if (searched.contains(tsym)) {
aoqi@0 468 return null;
aoqi@0 469 }
aoqi@0 470 searched.add(tsym);
aoqi@0 471
aoqi@0 472 for (com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(fieldName);
aoqi@0 473 e.scope != null; e = e.next()) {
aoqi@0 474 if (e.sym.kind == Kinds.VAR) {
aoqi@0 475 return (VarSymbol)e.sym;
aoqi@0 476 }
aoqi@0 477 }
aoqi@0 478
aoqi@0 479 //### If we found a VarSymbol above, but which did not pass
aoqi@0 480 //### the modifier filter, we should return failure here!
aoqi@0 481
aoqi@0 482 ClassSymbol encl = tsym.owner.enclClass();
aoqi@0 483 if (encl != null) {
aoqi@0 484 VarSymbol vsym = searchField(encl, fieldName, searched);
aoqi@0 485 if (vsym != null) {
aoqi@0 486 return vsym;
aoqi@0 487 }
aoqi@0 488 }
aoqi@0 489
aoqi@0 490 // search superclass
aoqi@0 491 Type superclass = tsym.getSuperclass();
aoqi@0 492 if (superclass.tsym != null) {
aoqi@0 493 VarSymbol vsym = searchField((ClassSymbol) superclass.tsym, fieldName, searched);
aoqi@0 494 if (vsym != null) {
aoqi@0 495 return vsym;
aoqi@0 496 }
aoqi@0 497 }
aoqi@0 498
aoqi@0 499 // search interfaces
aoqi@0 500 List<Type> intfs = tsym.getInterfaces();
aoqi@0 501 for (List<Type> l = intfs; l.nonEmpty(); l = l.tail) {
aoqi@0 502 Type intf = l.head;
aoqi@0 503 if (intf.isErroneous()) continue;
aoqi@0 504 VarSymbol vsym = searchField((ClassSymbol) intf.tsym, fieldName, searched);
aoqi@0 505 if (vsym != null) {
aoqi@0 506 return vsym;
aoqi@0 507 }
aoqi@0 508 }
aoqi@0 509
aoqi@0 510 return null;
aoqi@0 511 }
aoqi@0 512
aoqi@0 513 /** @see com.sun.tools.javadoc.ClassDocImpl#findConstructor */
aoqi@0 514 MethodSymbol findConstructor(ClassSymbol tsym, List<Type> paramTypes) {
aoqi@0 515 for (com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(names.init);
aoqi@0 516 e.scope != null; e = e.next()) {
aoqi@0 517 if (e.sym.kind == Kinds.MTH) {
aoqi@0 518 if (hasParameterTypes((MethodSymbol) e.sym, paramTypes)) {
aoqi@0 519 return (MethodSymbol) e.sym;
aoqi@0 520 }
aoqi@0 521 }
aoqi@0 522 }
aoqi@0 523 return null;
aoqi@0 524 }
aoqi@0 525
aoqi@0 526 /** @see com.sun.tools.javadoc.ClassDocImpl#findMethod */
aoqi@0 527 private MethodSymbol findMethod(ClassSymbol tsym, Name methodName, List<Type> paramTypes) {
aoqi@0 528 return searchMethod(tsym, methodName, paramTypes, new HashSet<ClassSymbol>());
aoqi@0 529 }
aoqi@0 530
aoqi@0 531 /** @see com.sun.tools.javadoc.ClassDocImpl#searchMethod */
aoqi@0 532 private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName,
aoqi@0 533 List<Type> paramTypes, Set<ClassSymbol> searched) {
aoqi@0 534 //### Note that this search is not necessarily what the compiler would do!
aoqi@0 535
aoqi@0 536 // do not match constructors
aoqi@0 537 if (methodName == names.init)
aoqi@0 538 return null;
aoqi@0 539
aoqi@0 540 if (searched.contains(tsym))
aoqi@0 541 return null;
aoqi@0 542 searched.add(tsym);
aoqi@0 543
aoqi@0 544 // search current class
aoqi@0 545 com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(methodName);
aoqi@0 546
aoqi@0 547 //### Using modifier filter here isn't really correct,
aoqi@0 548 //### but emulates the old behavior. Instead, we should
aoqi@0 549 //### apply the normal rules of visibility and inheritance.
aoqi@0 550
aoqi@0 551 if (paramTypes == null) {
aoqi@0 552 // If no parameters specified, we are allowed to return
aoqi@0 553 // any method with a matching name. In practice, the old
aoqi@0 554 // code returned the first method, which is now the last!
aoqi@0 555 // In order to provide textually identical results, we
aoqi@0 556 // attempt to emulate the old behavior.
aoqi@0 557 MethodSymbol lastFound = null;
aoqi@0 558 for (; e.scope != null; e = e.next()) {
aoqi@0 559 if (e.sym.kind == Kinds.MTH) {
aoqi@0 560 if (e.sym.name == methodName) {
aoqi@0 561 lastFound = (MethodSymbol)e.sym;
aoqi@0 562 }
aoqi@0 563 }
aoqi@0 564 }
aoqi@0 565 if (lastFound != null) {
aoqi@0 566 return lastFound;
aoqi@0 567 }
aoqi@0 568 } else {
aoqi@0 569 for (; e.scope != null; e = e.next()) {
aoqi@0 570 if (e.sym != null &&
aoqi@0 571 e.sym.kind == Kinds.MTH) {
aoqi@0 572 if (hasParameterTypes((MethodSymbol) e.sym, paramTypes)) {
aoqi@0 573 return (MethodSymbol) e.sym;
aoqi@0 574 }
aoqi@0 575 }
aoqi@0 576 }
aoqi@0 577 }
aoqi@0 578
aoqi@0 579 //### If we found a MethodSymbol above, but which did not pass
aoqi@0 580 //### the modifier filter, we should return failure here!
aoqi@0 581
aoqi@0 582 // search superclass
aoqi@0 583 Type superclass = tsym.getSuperclass();
aoqi@0 584 if (superclass.tsym != null) {
aoqi@0 585 MethodSymbol msym = searchMethod((ClassSymbol) superclass.tsym, methodName, paramTypes, searched);
aoqi@0 586 if (msym != null) {
aoqi@0 587 return msym;
aoqi@0 588 }
aoqi@0 589 }
aoqi@0 590
aoqi@0 591 // search interfaces
aoqi@0 592 List<Type> intfs = tsym.getInterfaces();
aoqi@0 593 for (List<Type> l = intfs; l.nonEmpty(); l = l.tail) {
aoqi@0 594 Type intf = l.head;
aoqi@0 595 if (intf.isErroneous()) continue;
aoqi@0 596 MethodSymbol msym = searchMethod((ClassSymbol) intf.tsym, methodName, paramTypes, searched);
aoqi@0 597 if (msym != null) {
aoqi@0 598 return msym;
aoqi@0 599 }
aoqi@0 600 }
aoqi@0 601
aoqi@0 602 // search enclosing class
aoqi@0 603 ClassSymbol encl = tsym.owner.enclClass();
aoqi@0 604 if (encl != null) {
aoqi@0 605 MethodSymbol msym = searchMethod(encl, methodName, paramTypes, searched);
aoqi@0 606 if (msym != null) {
aoqi@0 607 return msym;
aoqi@0 608 }
aoqi@0 609 }
aoqi@0 610
aoqi@0 611 return null;
aoqi@0 612 }
aoqi@0 613
aoqi@0 614 /** @see com.sun.tools.javadoc.ClassDocImpl */
aoqi@0 615 private boolean hasParameterTypes(MethodSymbol method, List<Type> paramTypes) {
aoqi@0 616 if (paramTypes == null)
aoqi@0 617 return true;
aoqi@0 618
aoqi@0 619 if (method.params().size() != paramTypes.size())
aoqi@0 620 return false;
aoqi@0 621
aoqi@0 622 List<Type> methodParamTypes = types.erasureRecursive(method.asType()).getParameterTypes();
aoqi@0 623
aoqi@0 624 return (Type.isErroneous(paramTypes))
aoqi@0 625 ? fuzzyMatch(paramTypes, methodParamTypes)
aoqi@0 626 : types.isSameTypes(paramTypes, methodParamTypes);
aoqi@0 627 }
aoqi@0 628
aoqi@0 629 boolean fuzzyMatch(List<Type> paramTypes, List<Type> methodParamTypes) {
aoqi@0 630 List<Type> l1 = paramTypes;
aoqi@0 631 List<Type> l2 = methodParamTypes;
aoqi@0 632 while (l1.nonEmpty()) {
aoqi@0 633 if (!fuzzyMatch(l1.head, l2.head))
aoqi@0 634 return false;
aoqi@0 635 l1 = l1.tail;
aoqi@0 636 l2 = l2.tail;
aoqi@0 637 }
aoqi@0 638 return true;
aoqi@0 639 }
aoqi@0 640
aoqi@0 641 boolean fuzzyMatch(Type paramType, Type methodParamType) {
aoqi@0 642 Boolean b = fuzzyMatcher.visit(paramType, methodParamType);
aoqi@0 643 return (b == Boolean.TRUE);
aoqi@0 644 }
aoqi@0 645
aoqi@0 646 TypeRelation fuzzyMatcher = new TypeRelation() {
aoqi@0 647 @Override
aoqi@0 648 public Boolean visitType(Type t, Type s) {
aoqi@0 649 if (t == s)
aoqi@0 650 return true;
aoqi@0 651
aoqi@0 652 if (s.isPartial())
aoqi@0 653 return visit(s, t);
aoqi@0 654
aoqi@0 655 switch (t.getTag()) {
aoqi@0 656 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
aoqi@0 657 case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
aoqi@0 658 return t.hasTag(s.getTag());
aoqi@0 659 default:
aoqi@0 660 throw new AssertionError("fuzzyMatcher " + t.getTag());
aoqi@0 661 }
aoqi@0 662 }
aoqi@0 663
aoqi@0 664 @Override
aoqi@0 665 public Boolean visitArrayType(ArrayType t, Type s) {
aoqi@0 666 if (t == s)
aoqi@0 667 return true;
aoqi@0 668
aoqi@0 669 if (s.isPartial())
aoqi@0 670 return visit(s, t);
aoqi@0 671
aoqi@0 672 return s.hasTag(ARRAY)
aoqi@0 673 && visit(t.elemtype, types.elemtype(s));
aoqi@0 674 }
aoqi@0 675
aoqi@0 676 @Override
aoqi@0 677 public Boolean visitClassType(ClassType t, Type s) {
aoqi@0 678 if (t == s)
aoqi@0 679 return true;
aoqi@0 680
aoqi@0 681 if (s.isPartial())
aoqi@0 682 return visit(s, t);
aoqi@0 683
aoqi@0 684 return t.tsym == s.tsym;
aoqi@0 685 }
aoqi@0 686
aoqi@0 687 @Override
aoqi@0 688 public Boolean visitErrorType(ErrorType t, Type s) {
aoqi@0 689 return s.hasTag(CLASS)
aoqi@0 690 && t.tsym.name == ((ClassType) s).tsym.name;
aoqi@0 691 }
aoqi@0 692 };
aoqi@0 693
aoqi@0 694 public TypeMirror getTypeMirror(TreePath path) {
aoqi@0 695 Tree t = path.getLeaf();
aoqi@0 696 return ((JCTree)t).type;
aoqi@0 697 }
aoqi@0 698
aoqi@0 699 public JavacScope getScope(TreePath path) {
aoqi@0 700 return new JavacScope(getAttrContext(path));
aoqi@0 701 }
aoqi@0 702
aoqi@0 703 public String getDocComment(TreePath path) {
aoqi@0 704 CompilationUnitTree t = path.getCompilationUnit();
aoqi@0 705 Tree leaf = path.getLeaf();
aoqi@0 706 if (t instanceof JCTree.JCCompilationUnit && leaf instanceof JCTree) {
aoqi@0 707 JCCompilationUnit cu = (JCCompilationUnit) t;
aoqi@0 708 if (cu.docComments != null) {
aoqi@0 709 return cu.docComments.getCommentText((JCTree) leaf);
aoqi@0 710 }
aoqi@0 711 }
aoqi@0 712 return null;
aoqi@0 713 }
aoqi@0 714
aoqi@0 715 public DocCommentTree getDocCommentTree(TreePath path) {
aoqi@0 716 CompilationUnitTree t = path.getCompilationUnit();
aoqi@0 717 Tree leaf = path.getLeaf();
aoqi@0 718 if (t instanceof JCTree.JCCompilationUnit && leaf instanceof JCTree) {
aoqi@0 719 JCCompilationUnit cu = (JCCompilationUnit) t;
aoqi@0 720 if (cu.docComments != null) {
aoqi@0 721 return cu.docComments.getCommentTree((JCTree) leaf);
aoqi@0 722 }
aoqi@0 723 }
aoqi@0 724 return null;
aoqi@0 725 }
aoqi@0 726
aoqi@0 727 public boolean isAccessible(Scope scope, TypeElement type) {
aoqi@0 728 if (scope instanceof JavacScope && type instanceof ClassSymbol) {
aoqi@0 729 Env<AttrContext> env = ((JavacScope) scope).env;
aoqi@0 730 return resolve.isAccessible(env, (ClassSymbol)type, true);
aoqi@0 731 } else
aoqi@0 732 return false;
aoqi@0 733 }
aoqi@0 734
aoqi@0 735 public boolean isAccessible(Scope scope, Element member, DeclaredType type) {
aoqi@0 736 if (scope instanceof JavacScope
aoqi@0 737 && member instanceof Symbol
aoqi@0 738 && type instanceof com.sun.tools.javac.code.Type) {
aoqi@0 739 Env<AttrContext> env = ((JavacScope) scope).env;
aoqi@0 740 return resolve.isAccessible(env, (com.sun.tools.javac.code.Type)type, (Symbol)member, true);
aoqi@0 741 } else
aoqi@0 742 return false;
aoqi@0 743 }
aoqi@0 744
aoqi@0 745 private Env<AttrContext> getAttrContext(TreePath path) {
aoqi@0 746 if (!(path.getLeaf() instanceof JCTree)) // implicit null-check
aoqi@0 747 throw new IllegalArgumentException();
aoqi@0 748
aoqi@0 749 // if we're being invoked from a Tree API client via parse/enter/analyze,
aoqi@0 750 // we need to make sure all the classes have been entered;
aoqi@0 751 // if we're being invoked from JSR 199 or JSR 269, then the classes
aoqi@0 752 // will already have been entered.
aoqi@0 753 if (javacTaskImpl != null) {
aoqi@0 754 try {
aoqi@0 755 javacTaskImpl.enter(null);
aoqi@0 756 } catch (IOException e) {
aoqi@0 757 throw new Error("unexpected error while entering symbols: " + e);
aoqi@0 758 }
aoqi@0 759 }
aoqi@0 760
aoqi@0 761
aoqi@0 762 JCCompilationUnit unit = (JCCompilationUnit) path.getCompilationUnit();
aoqi@0 763 Copier copier = createCopier(treeMaker.forToplevel(unit));
aoqi@0 764
aoqi@0 765 Env<AttrContext> env = null;
aoqi@0 766 JCMethodDecl method = null;
aoqi@0 767 JCVariableDecl field = null;
aoqi@0 768
aoqi@0 769 List<Tree> l = List.nil();
aoqi@0 770 TreePath p = path;
aoqi@0 771 while (p != null) {
aoqi@0 772 l = l.prepend(p.getLeaf());
aoqi@0 773 p = p.getParentPath();
aoqi@0 774 }
aoqi@0 775
aoqi@0 776 for ( ; l.nonEmpty(); l = l.tail) {
aoqi@0 777 Tree tree = l.head;
aoqi@0 778 switch (tree.getKind()) {
aoqi@0 779 case COMPILATION_UNIT:
aoqi@0 780 // System.err.println("COMP: " + ((JCCompilationUnit)tree).sourcefile);
aoqi@0 781 env = enter.getTopLevelEnv((JCCompilationUnit)tree);
aoqi@0 782 break;
aoqi@0 783 case ANNOTATION_TYPE:
aoqi@0 784 case CLASS:
aoqi@0 785 case ENUM:
aoqi@0 786 case INTERFACE:
aoqi@0 787 // System.err.println("CLASS: " + ((JCClassDecl)tree).sym.getSimpleName());
aoqi@0 788 env = enter.getClassEnv(((JCClassDecl)tree).sym);
aoqi@0 789 break;
aoqi@0 790 case METHOD:
aoqi@0 791 // System.err.println("METHOD: " + ((JCMethodDecl)tree).sym.getSimpleName());
aoqi@0 792 method = (JCMethodDecl)tree;
aoqi@0 793 env = memberEnter.getMethodEnv(method, env);
aoqi@0 794 break;
aoqi@0 795 case VARIABLE:
aoqi@0 796 // System.err.println("FIELD: " + ((JCVariableDecl)tree).sym.getSimpleName());
aoqi@0 797 field = (JCVariableDecl)tree;
aoqi@0 798 break;
aoqi@0 799 case BLOCK: {
aoqi@0 800 // System.err.println("BLOCK: ");
aoqi@0 801 if (method != null) {
aoqi@0 802 try {
aoqi@0 803 Assert.check(method.body == tree);
aoqi@0 804 method.body = copier.copy((JCBlock)tree, (JCTree) path.getLeaf());
aoqi@0 805 env = attribStatToTree(method.body, env, copier.leafCopy);
aoqi@0 806 } finally {
aoqi@0 807 method.body = (JCBlock) tree;
aoqi@0 808 }
aoqi@0 809 } else {
aoqi@0 810 JCBlock body = copier.copy((JCBlock)tree, (JCTree) path.getLeaf());
aoqi@0 811 env = attribStatToTree(body, env, copier.leafCopy);
aoqi@0 812 }
aoqi@0 813 return env;
aoqi@0 814 }
aoqi@0 815 default:
aoqi@0 816 // System.err.println("DEFAULT: " + tree.getKind());
aoqi@0 817 if (field != null && field.getInitializer() == tree) {
aoqi@0 818 env = memberEnter.getInitEnv(field, env);
aoqi@0 819 JCExpression expr = copier.copy((JCExpression)tree, (JCTree) path.getLeaf());
aoqi@0 820 env = attribExprToTree(expr, env, copier.leafCopy);
aoqi@0 821 return env;
aoqi@0 822 }
aoqi@0 823 }
aoqi@0 824 }
aoqi@0 825 return (field != null) ? memberEnter.getInitEnv(field, env) : env;
aoqi@0 826 }
aoqi@0 827
aoqi@0 828 private Env<AttrContext> attribStatToTree(JCTree stat, Env<AttrContext>env, JCTree tree) {
aoqi@0 829 JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
aoqi@0 830 try {
aoqi@0 831 return attr.attribStatToTree(stat, env, tree);
aoqi@0 832 } finally {
aoqi@0 833 log.useSource(prev);
aoqi@0 834 }
aoqi@0 835 }
aoqi@0 836
aoqi@0 837 private Env<AttrContext> attribExprToTree(JCExpression expr, Env<AttrContext>env, JCTree tree) {
aoqi@0 838 JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
aoqi@0 839 try {
aoqi@0 840 return attr.attribExprToTree(expr, env, tree);
aoqi@0 841 } finally {
aoqi@0 842 log.useSource(prev);
aoqi@0 843 }
aoqi@0 844 }
aoqi@0 845
aoqi@0 846 /**
aoqi@0 847 * Makes a copy of a tree, noting the value resulting from copying a particular leaf.
aoqi@0 848 **/
aoqi@0 849 protected static class Copier extends TreeCopier<JCTree> {
aoqi@0 850 JCTree leafCopy = null;
aoqi@0 851
aoqi@0 852 protected Copier(TreeMaker M) {
aoqi@0 853 super(M);
aoqi@0 854 }
aoqi@0 855
aoqi@0 856 @Override
aoqi@0 857 public <T extends JCTree> T copy(T t, JCTree leaf) {
aoqi@0 858 T t2 = super.copy(t, leaf);
aoqi@0 859 if (t == leaf)
aoqi@0 860 leafCopy = t2;
aoqi@0 861 return t2;
aoqi@0 862 }
aoqi@0 863 }
aoqi@0 864
aoqi@0 865 protected Copier createCopier(TreeMaker maker) {
aoqi@0 866 return new Copier(maker);
aoqi@0 867 }
aoqi@0 868
aoqi@0 869 /**
aoqi@0 870 * Gets the original type from the ErrorType object.
aoqi@0 871 * @param errorType The errorType for which we want to get the original type.
aoqi@0 872 * @returns TypeMirror corresponding to the original type, replaced by the ErrorType.
aoqi@0 873 * noType (type.tag == NONE) is returned if there is no original type.
aoqi@0 874 */
aoqi@0 875 public TypeMirror getOriginalType(javax.lang.model.type.ErrorType errorType) {
aoqi@0 876 if (errorType instanceof com.sun.tools.javac.code.Type.ErrorType) {
aoqi@0 877 return ((com.sun.tools.javac.code.Type.ErrorType)errorType).getOriginalType();
aoqi@0 878 }
aoqi@0 879
aoqi@0 880 return com.sun.tools.javac.code.Type.noType;
aoqi@0 881 }
aoqi@0 882
aoqi@0 883 /**
aoqi@0 884 * Prints a message of the specified kind at the location of the
aoqi@0 885 * tree within the provided compilation unit
aoqi@0 886 *
aoqi@0 887 * @param kind the kind of message
aoqi@0 888 * @param msg the message, or an empty string if none
aoqi@0 889 * @param t the tree to use as a position hint
aoqi@0 890 * @param root the compilation unit that contains tree
aoqi@0 891 */
aoqi@0 892 public void printMessage(Diagnostic.Kind kind, CharSequence msg,
aoqi@0 893 com.sun.source.tree.Tree t,
aoqi@0 894 com.sun.source.tree.CompilationUnitTree root) {
aoqi@0 895 printMessage(kind, msg, ((JCTree) t).pos(), root);
aoqi@0 896 }
aoqi@0 897
aoqi@0 898 public void printMessage(Diagnostic.Kind kind, CharSequence msg,
aoqi@0 899 com.sun.source.doctree.DocTree t,
aoqi@0 900 com.sun.source.doctree.DocCommentTree c,
aoqi@0 901 com.sun.source.tree.CompilationUnitTree root) {
aoqi@0 902 printMessage(kind, msg, ((DCTree) t).pos((DCDocComment) c), root);
aoqi@0 903 }
aoqi@0 904
aoqi@0 905 private void printMessage(Diagnostic.Kind kind, CharSequence msg,
aoqi@0 906 JCDiagnostic.DiagnosticPosition pos,
aoqi@0 907 com.sun.source.tree.CompilationUnitTree root) {
aoqi@0 908 JavaFileObject oldSource = null;
aoqi@0 909 JavaFileObject newSource = null;
aoqi@0 910
aoqi@0 911 newSource = root.getSourceFile();
aoqi@0 912 if (newSource == null) {
aoqi@0 913 pos = null;
aoqi@0 914 } else {
aoqi@0 915 oldSource = log.useSource(newSource);
aoqi@0 916 }
aoqi@0 917
aoqi@0 918 try {
aoqi@0 919 switch (kind) {
aoqi@0 920 case ERROR:
aoqi@0 921 boolean prev = log.multipleErrors;
aoqi@0 922 try {
aoqi@0 923 log.error(pos, "proc.messager", msg.toString());
aoqi@0 924 } finally {
aoqi@0 925 log.multipleErrors = prev;
aoqi@0 926 }
aoqi@0 927 break;
aoqi@0 928
aoqi@0 929 case WARNING:
aoqi@0 930 log.warning(pos, "proc.messager", msg.toString());
aoqi@0 931 break;
aoqi@0 932
aoqi@0 933 case MANDATORY_WARNING:
aoqi@0 934 log.mandatoryWarning(pos, "proc.messager", msg.toString());
aoqi@0 935 break;
aoqi@0 936
aoqi@0 937 default:
aoqi@0 938 log.note(pos, "proc.messager", msg.toString());
aoqi@0 939 }
aoqi@0 940 } finally {
aoqi@0 941 if (oldSource != null)
aoqi@0 942 log.useSource(oldSource);
aoqi@0 943 }
aoqi@0 944 }
aoqi@0 945
aoqi@0 946 @Override
aoqi@0 947 public TypeMirror getLub(CatchTree tree) {
aoqi@0 948 JCCatch ct = (JCCatch) tree;
aoqi@0 949 JCVariableDecl v = ct.param;
aoqi@0 950 if (v.type != null && v.type.getKind() == TypeKind.UNION) {
aoqi@0 951 UnionClassType ut = (UnionClassType) v.type;
aoqi@0 952 return ut.getLub();
aoqi@0 953 } else {
aoqi@0 954 return v.type;
aoqi@0 955 }
aoqi@0 956 }
aoqi@0 957 }

mercurial