src/share/jaxws_classes/com/sun/tools/internal/jxc/model/nav/ApNavigator.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 450
b0c2840e2513
parent 0
373ffda63c9a
child 919
3419d2eab6f8
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 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.internal.jxc.model.nav;
aoqi@0 27
aoqi@0 28 import com.sun.source.tree.CompilationUnitTree;
aoqi@0 29 import com.sun.source.util.TreePath;
aoqi@0 30 import com.sun.source.util.Trees;
aoqi@0 31 import com.sun.xml.internal.bind.v2.model.nav.Navigator;
aoqi@0 32 import com.sun.xml.internal.bind.v2.runtime.Location;
aoqi@0 33
aoqi@0 34 import javax.annotation.processing.ProcessingEnvironment;
aoqi@0 35 import javax.lang.model.element.AnnotationMirror;
aoqi@0 36 import javax.lang.model.element.Element;
aoqi@0 37 import javax.lang.model.element.ElementKind;
aoqi@0 38 import javax.lang.model.element.ExecutableElement;
aoqi@0 39 import javax.lang.model.element.Modifier;
aoqi@0 40 import javax.lang.model.element.TypeElement;
aoqi@0 41 import javax.lang.model.element.TypeParameterElement;
aoqi@0 42 import javax.lang.model.element.VariableElement;
aoqi@0 43 import javax.lang.model.type.ArrayType;
aoqi@0 44 import javax.lang.model.type.DeclaredType;
aoqi@0 45 import javax.lang.model.type.PrimitiveType;
aoqi@0 46 import javax.lang.model.type.TypeKind;
aoqi@0 47 import javax.lang.model.type.TypeMirror;
aoqi@0 48 import javax.lang.model.type.TypeVariable;
aoqi@0 49 import javax.lang.model.type.TypeVisitor;
aoqi@0 50 import javax.lang.model.type.WildcardType;
aoqi@0 51 import javax.lang.model.util.ElementFilter;
aoqi@0 52 import javax.lang.model.util.Elements;
aoqi@0 53 import javax.lang.model.util.SimpleTypeVisitor6;
aoqi@0 54 import javax.lang.model.util.Types;
aoqi@0 55 import java.lang.annotation.Annotation;
aoqi@0 56 import java.util.Collection;
aoqi@0 57 import java.util.HashMap;
aoqi@0 58 import java.util.HashSet;
aoqi@0 59 import java.util.List;
aoqi@0 60 import java.util.Map;
aoqi@0 61
aoqi@0 62 /**
aoqi@0 63 * {@link Navigator} implementation for annotation processing.
aoqi@0 64 * TODO: check the spec on how generics are supposed to be handled
aoqi@0 65 *
aoqi@0 66 * @author Kohsuke Kawaguchi (kk@kohsuke.org)
aoqi@0 67 */
aoqi@0 68 public final class ApNavigator implements Navigator<TypeMirror, TypeElement, VariableElement, ExecutableElement> {
aoqi@0 69
aoqi@0 70 private final ProcessingEnvironment env;
aoqi@0 71
aoqi@0 72 private final PrimitiveType primitiveByte;
aoqi@0 73
aoqi@0 74 public ApNavigator(ProcessingEnvironment env) {
aoqi@0 75 this.env = env;
aoqi@0 76 this.primitiveByte = env.getTypeUtils().getPrimitiveType(TypeKind.BYTE);
aoqi@0 77 }
aoqi@0 78
aoqi@0 79 public TypeElement getSuperClass(TypeElement typeElement) {
aoqi@0 80 if (typeElement.getKind().equals(ElementKind.CLASS)) {
aoqi@0 81 TypeMirror sup = typeElement.getSuperclass();
aoqi@0 82 if (!sup.getKind().equals(TypeKind.NONE))
aoqi@0 83 return (TypeElement) ((DeclaredType) sup).asElement();
aoqi@0 84 else
aoqi@0 85 return null;
aoqi@0 86 }
aoqi@0 87 return env.getElementUtils().getTypeElement(Object.class.getName());
aoqi@0 88 }
aoqi@0 89
aoqi@0 90 public TypeMirror getBaseClass(TypeMirror type, TypeElement sup) {
aoqi@0 91 return baseClassFinder.visit(type, sup);
aoqi@0 92 }
aoqi@0 93
aoqi@0 94 public String getClassName(TypeElement t) {
aoqi@0 95 return t.getQualifiedName().toString();
aoqi@0 96 }
aoqi@0 97
aoqi@0 98 public String getTypeName(TypeMirror typeMirror) {
aoqi@0 99 return typeMirror.toString();
aoqi@0 100 }
aoqi@0 101
aoqi@0 102 public String getClassShortName(TypeElement t) {
aoqi@0 103 return t.getSimpleName().toString();
aoqi@0 104 }
aoqi@0 105
aoqi@0 106 public Collection<VariableElement> getDeclaredFields(TypeElement typeElement) {
aoqi@0 107 return ElementFilter.fieldsIn(typeElement.getEnclosedElements());
aoqi@0 108 }
aoqi@0 109
aoqi@0 110 public VariableElement getDeclaredField(TypeElement clazz, String fieldName) {
aoqi@0 111 for (VariableElement fd : ElementFilter.fieldsIn(clazz.getEnclosedElements())) {
aoqi@0 112 if (fd.getSimpleName().toString().equals(fieldName))
aoqi@0 113 return fd;
aoqi@0 114 }
aoqi@0 115 return null;
aoqi@0 116 }
aoqi@0 117
aoqi@0 118 public Collection<ExecutableElement> getDeclaredMethods(TypeElement typeElement) {
aoqi@0 119 return ElementFilter.methodsIn(typeElement.getEnclosedElements());
aoqi@0 120 }
aoqi@0 121
aoqi@0 122 public TypeElement getDeclaringClassForField(VariableElement f) {
aoqi@0 123 return (TypeElement) f.getEnclosingElement();
aoqi@0 124 }
aoqi@0 125
aoqi@0 126 public TypeElement getDeclaringClassForMethod(ExecutableElement m) {
aoqi@0 127 return (TypeElement) m.getEnclosingElement();
aoqi@0 128 }
aoqi@0 129
aoqi@0 130 public TypeMirror getFieldType(VariableElement f) {
aoqi@0 131 return f.asType();
aoqi@0 132 }
aoqi@0 133
aoqi@0 134 public String getFieldName(VariableElement f) {
aoqi@0 135 return f.getSimpleName().toString();
aoqi@0 136 }
aoqi@0 137
aoqi@0 138 public String getMethodName(ExecutableElement m) {
aoqi@0 139 return m.getSimpleName().toString();
aoqi@0 140 }
aoqi@0 141
aoqi@0 142 public TypeMirror getReturnType(ExecutableElement m) {
aoqi@0 143 return m.getReturnType();
aoqi@0 144 }
aoqi@0 145
aoqi@0 146 public TypeMirror[] getMethodParameters(ExecutableElement m) {
aoqi@0 147 Collection<? extends VariableElement> ps = m.getParameters();
aoqi@0 148 TypeMirror[] r = new TypeMirror[ps.size()];
aoqi@0 149 int i=0;
aoqi@0 150 for (VariableElement p : ps)
aoqi@0 151 r[i++] = p.asType();
aoqi@0 152 return r;
aoqi@0 153 }
aoqi@0 154
aoqi@0 155 public boolean isStaticMethod(ExecutableElement m) {
aoqi@0 156 return hasModifier(m, Modifier.STATIC);
aoqi@0 157 }
aoqi@0 158
aoqi@0 159 public boolean isFinalMethod(ExecutableElement m) {
aoqi@0 160 return hasModifier(m, Modifier.FINAL);
aoqi@0 161 }
aoqi@0 162
aoqi@0 163 private boolean hasModifier(Element d, Modifier mod) {
aoqi@0 164 return d.getModifiers().contains(mod);
aoqi@0 165 }
aoqi@0 166
aoqi@0 167 public boolean isSubClassOf(TypeMirror sub, TypeMirror sup) {
aoqi@0 168 if(sup==DUMMY)
aoqi@0 169 // see ref(). if the sub type is known to Annotation Processing,
aoqi@0 170 // its base class must be known. Thus if the sup is DUMMY,
aoqi@0 171 // it cannot possibly be the super type.
aoqi@0 172 return false;
aoqi@0 173 return env.getTypeUtils().isSubtype(sub,sup);
aoqi@0 174 }
aoqi@0 175
aoqi@0 176 private String getSourceClassName(Class clazz) {
aoqi@0 177 Class<?> d = clazz.getDeclaringClass();
aoqi@0 178 if(d==null)
aoqi@0 179 return clazz.getName();
aoqi@0 180 else {
aoqi@0 181 String shortName = clazz.getName().substring(d.getName().length()+1/*for $*/);
aoqi@0 182 return getSourceClassName(d)+'.'+shortName;
aoqi@0 183 }
aoqi@0 184 }
aoqi@0 185
aoqi@0 186 public TypeMirror ref(Class c) {
aoqi@0 187 if(c.isArray())
aoqi@0 188 return env.getTypeUtils().getArrayType( ref(c.getComponentType()) );
aoqi@0 189 if(c.isPrimitive())
aoqi@0 190 return getPrimitive(c);
aoqi@0 191 TypeElement t = env.getElementUtils().getTypeElement(getSourceClassName(c));
aoqi@0 192 // Annotation Processing only operates on a set of classes used in the compilation,
aoqi@0 193 // and it won't recognize additional classes (even if they are visible from javac)
aoqi@0 194 // and return null.
aoqi@0 195 //
aoqi@0 196 // this is causing a problem where we check if a type is collection.
aoqi@0 197 // so until the problem is fixed in Annotation Processing, work around the issue
aoqi@0 198 // by returning a dummy token
aoqi@0 199 // TODO: check if this is still valid
aoqi@0 200 if(t==null)
aoqi@0 201 return DUMMY;
aoqi@0 202 return env.getTypeUtils().getDeclaredType(t);
aoqi@0 203 }
aoqi@0 204
aoqi@0 205 public TypeMirror use(TypeElement t) {
aoqi@0 206 assert t != null;
aoqi@0 207 return env.getTypeUtils().getDeclaredType(t);
aoqi@0 208 }
aoqi@0 209
aoqi@0 210 public TypeElement asDecl(TypeMirror m) {
aoqi@0 211 m = env.getTypeUtils().erasure(m);
aoqi@0 212 if (m.getKind().equals(TypeKind.DECLARED)) {
aoqi@0 213 DeclaredType d = (DeclaredType) m;
aoqi@0 214 return (TypeElement) d.asElement();
aoqi@0 215 } else
aoqi@0 216 return null;
aoqi@0 217 }
aoqi@0 218
aoqi@0 219 public TypeElement asDecl(Class c) {
aoqi@0 220 return env.getElementUtils().getTypeElement(getSourceClassName(c));
aoqi@0 221 }
aoqi@0 222
aoqi@0 223 public TypeMirror erasure(TypeMirror t) {
aoqi@0 224 Types tu = env.getTypeUtils();
aoqi@0 225 t = tu.erasure(t);
aoqi@0 226 if (t.getKind().equals(TypeKind.DECLARED)) {
aoqi@0 227 DeclaredType dt = (DeclaredType)t;
aoqi@0 228 if (!dt.getTypeArguments().isEmpty())
aoqi@0 229 return tu.getDeclaredType((TypeElement) dt.asElement());
aoqi@0 230 }
aoqi@0 231 return t;
aoqi@0 232 }
aoqi@0 233
aoqi@0 234 public boolean isAbstract(TypeElement clazz) {
aoqi@0 235 return hasModifier(clazz,Modifier.ABSTRACT);
aoqi@0 236 }
aoqi@0 237
aoqi@0 238 public boolean isFinal(TypeElement clazz) {
aoqi@0 239 return hasModifier(clazz, Modifier.FINAL);
aoqi@0 240 }
aoqi@0 241
aoqi@0 242 public VariableElement[] getEnumConstants(TypeElement clazz) {
aoqi@0 243 List<? extends Element> elements = env.getElementUtils().getAllMembers(clazz);
aoqi@0 244 Collection<VariableElement> constants = new HashSet<VariableElement>();
aoqi@0 245 for (Element element : elements) {
aoqi@0 246 if (element.getKind().equals(ElementKind.ENUM_CONSTANT)) {
aoqi@0 247 constants.add((VariableElement) element);
aoqi@0 248 }
aoqi@0 249 }
aoqi@0 250 return constants.toArray(new VariableElement[constants.size()]);
aoqi@0 251 }
aoqi@0 252
aoqi@0 253 public TypeMirror getVoidType() {
aoqi@0 254 return env.getTypeUtils().getNoType(TypeKind.VOID);
aoqi@0 255 }
aoqi@0 256
aoqi@0 257 public String getPackageName(TypeElement clazz) {
aoqi@0 258 return env.getElementUtils().getPackageOf(clazz).getQualifiedName().toString();
aoqi@0 259 }
aoqi@0 260
aoqi@0 261 @Override
aoqi@0 262 public TypeElement loadObjectFactory(TypeElement referencePoint, String packageName) {
aoqi@0 263 return env.getElementUtils().getTypeElement(packageName + ".ObjectFactory");
aoqi@0 264 }
aoqi@0 265
aoqi@0 266 public boolean isBridgeMethod(ExecutableElement method) {
aoqi@0 267 return method.getModifiers().contains(Modifier.VOLATILE);
aoqi@0 268 }
aoqi@0 269
aoqi@0 270 public boolean isOverriding(ExecutableElement method, TypeElement base) {
aoqi@0 271 Elements elements = env.getElementUtils();
aoqi@0 272
aoqi@0 273 while (true) {
aoqi@0 274 for (ExecutableElement m : ElementFilter.methodsIn(elements.getAllMembers(base))) {
aoqi@0 275 if (elements.overrides(method, m, base))
aoqi@0 276 return true;
aoqi@0 277 }
aoqi@0 278
aoqi@0 279 if (base.getSuperclass().getKind().equals(TypeKind.NONE))
aoqi@0 280 return false;
aoqi@0 281 base = (TypeElement) env.getTypeUtils().asElement(base.getSuperclass());
aoqi@0 282 }
aoqi@0 283 }
aoqi@0 284
aoqi@0 285 public boolean isInterface(TypeElement clazz) {
aoqi@0 286 return clazz.getKind().isInterface();
aoqi@0 287 }
aoqi@0 288
aoqi@0 289 public boolean isTransient(VariableElement f) {
aoqi@0 290 return f.getModifiers().contains(Modifier.TRANSIENT);
aoqi@0 291 }
aoqi@0 292
aoqi@0 293 public boolean isInnerClass(TypeElement clazz) {
aoqi@0 294 return clazz.getEnclosingElement() != null && !clazz.getModifiers().contains(Modifier.STATIC);
aoqi@0 295 }
aoqi@0 296
aoqi@0 297 @Override
aoqi@0 298 public boolean isSameType(TypeMirror t1, TypeMirror t2) {
aoqi@0 299 return env.getTypeUtils().isSameType(t1, t2);
aoqi@0 300 }
aoqi@0 301
aoqi@0 302 public boolean isArray(TypeMirror type) {
aoqi@0 303 return type != null && type.getKind().equals(TypeKind.ARRAY);
aoqi@0 304 }
aoqi@0 305
aoqi@0 306 public boolean isArrayButNotByteArray(TypeMirror t) {
aoqi@0 307 if(!isArray(t))
aoqi@0 308 return false;
aoqi@0 309
aoqi@0 310 ArrayType at = (ArrayType) t;
aoqi@0 311 TypeMirror ct = at.getComponentType();
aoqi@0 312
aoqi@0 313 return !ct.equals(primitiveByte);
aoqi@0 314 }
aoqi@0 315
aoqi@0 316 public TypeMirror getComponentType(TypeMirror t) {
aoqi@0 317 if (isArray(t)) {
aoqi@0 318 ArrayType at = (ArrayType) t;
aoqi@0 319 return at.getComponentType();
aoqi@0 320 }
aoqi@0 321
aoqi@0 322 throw new IllegalArgumentException();
aoqi@0 323 }
aoqi@0 324
aoqi@0 325 public TypeMirror getTypeArgument(TypeMirror typeMirror, int i) {
aoqi@0 326 if (typeMirror != null && typeMirror.getKind().equals(TypeKind.DECLARED)) {
aoqi@0 327 DeclaredType declaredType = (DeclaredType) typeMirror;
aoqi@0 328 TypeMirror[] args = declaredType.getTypeArguments().toArray(new TypeMirror[declaredType.getTypeArguments().size()]);
aoqi@0 329 return args[i];
aoqi@0 330 } else throw new IllegalArgumentException();
aoqi@0 331 }
aoqi@0 332
aoqi@0 333 public boolean isParameterizedType(TypeMirror typeMirror) {
aoqi@0 334 if (typeMirror != null && typeMirror.getKind().equals(TypeKind.DECLARED)) {
aoqi@0 335 DeclaredType d = (DeclaredType) typeMirror;
aoqi@0 336 return !d.getTypeArguments().isEmpty();
aoqi@0 337 }
aoqi@0 338 return false;
aoqi@0 339 }
aoqi@0 340
aoqi@0 341 public boolean isPrimitive(TypeMirror t) {
aoqi@0 342 return t.getKind().isPrimitive();
aoqi@0 343 }
aoqi@0 344
aoqi@0 345 private static final Map<Class, TypeKind> primitives = new HashMap<Class, TypeKind>();
aoqi@0 346
aoqi@0 347 static {
aoqi@0 348 primitives.put(Integer.TYPE, TypeKind.INT);
aoqi@0 349 primitives.put(Byte.TYPE, TypeKind.BYTE);
aoqi@0 350 primitives.put(Float.TYPE, TypeKind.FLOAT);
aoqi@0 351 primitives.put(Boolean.TYPE, TypeKind.BOOLEAN);
aoqi@0 352 primitives.put(Short.TYPE, TypeKind.SHORT);
aoqi@0 353 primitives.put(Long.TYPE, TypeKind.LONG);
aoqi@0 354 primitives.put(Double.TYPE, TypeKind.DOUBLE);
aoqi@0 355 primitives.put(Character.TYPE, TypeKind.CHAR);
aoqi@0 356 }
aoqi@0 357
aoqi@0 358 public TypeMirror getPrimitive(Class primitiveType) {
aoqi@0 359 assert primitiveType.isPrimitive();
aoqi@0 360 if(primitiveType==void.class)
aoqi@0 361 return getVoidType();
aoqi@0 362 return env.getTypeUtils().getPrimitiveType(primitives.get(primitiveType));
aoqi@0 363 }
aoqi@0 364
aoqi@0 365 /**
aoqi@0 366 * see {@link #ref(Class)}.
aoqi@0 367 */
aoqi@0 368 private static final TypeMirror DUMMY = new TypeMirror() {
aoqi@0 369 @Override
aoqi@0 370 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
aoqi@0 371 throw new IllegalStateException();
aoqi@0 372 }
aoqi@0 373
aoqi@0 374 @Override
aoqi@0 375 public TypeKind getKind() {
aoqi@0 376 throw new IllegalStateException();
aoqi@0 377 }
aoqi@0 378
aoqi@0 379 // @Override
aoqi@0 380 public List<? extends AnnotationMirror> getAnnotationMirrors() {
aoqi@0 381 throw new IllegalStateException();
aoqi@0 382 }
aoqi@0 383
aoqi@0 384 // @Override
aoqi@0 385 public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
aoqi@0 386 throw new IllegalStateException();
aoqi@0 387 }
aoqi@0 388
aoqi@0 389 // @Override
aoqi@0 390 public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
aoqi@0 391 throw new IllegalStateException();
aoqi@0 392 }
aoqi@0 393 };
aoqi@0 394
aoqi@0 395 public Location getClassLocation(TypeElement typeElement) {
aoqi@0 396 Trees trees = Trees.instance(env);
aoqi@0 397 return getLocation(typeElement.getQualifiedName().toString(), trees.getPath(typeElement));
aoqi@0 398 }
aoqi@0 399
aoqi@0 400 public Location getFieldLocation(VariableElement variableElement) {
aoqi@0 401 return getLocation(variableElement);
aoqi@0 402 }
aoqi@0 403
aoqi@0 404 public Location getMethodLocation(ExecutableElement executableElement) {
aoqi@0 405 return getLocation(executableElement);
aoqi@0 406 }
aoqi@0 407
aoqi@0 408 public boolean hasDefaultConstructor(TypeElement t) {
aoqi@0 409 if (t == null || !t.getKind().equals(ElementKind.CLASS))
aoqi@0 410 return false;
aoqi@0 411
aoqi@0 412 for (ExecutableElement init : ElementFilter.constructorsIn(env.getElementUtils().getAllMembers(t))) {
aoqi@0 413 if (init.getParameters().isEmpty())
aoqi@0 414 return true;
aoqi@0 415 }
aoqi@0 416 return false;
aoqi@0 417 }
aoqi@0 418
aoqi@0 419 public boolean isStaticField(VariableElement f) {
aoqi@0 420 return hasModifier(f,Modifier.STATIC);
aoqi@0 421 }
aoqi@0 422
aoqi@0 423 public boolean isPublicMethod(ExecutableElement m) {
aoqi@0 424 return hasModifier(m,Modifier.PUBLIC);
aoqi@0 425 }
aoqi@0 426
aoqi@0 427 public boolean isPublicField(VariableElement f) {
aoqi@0 428 return hasModifier(f,Modifier.PUBLIC);
aoqi@0 429 }
aoqi@0 430
aoqi@0 431 public boolean isEnum(TypeElement t) {
aoqi@0 432 return t != null && t.getKind().equals(ElementKind.ENUM);
aoqi@0 433 }
aoqi@0 434
aoqi@0 435 private Location getLocation(Element element) {
aoqi@0 436 Trees trees = Trees.instance(env);
aoqi@0 437 return getLocation(
aoqi@0 438 ((TypeElement) element.getEnclosingElement()).getQualifiedName() + "." + element.getSimpleName(),
aoqi@0 439 trees.getPath(element)
aoqi@0 440 );
aoqi@0 441 }
aoqi@0 442
aoqi@0 443 private Location getLocation(final String name, final TreePath treePath) {
aoqi@0 444 return new Location() {
aoqi@0 445 public String toString() {
aoqi@0 446 if (treePath == null)
aoqi@0 447 return name + " (Unknown Source)";
aoqi@0 448 // just like stack trace, we just print the file name and
aoqi@0 449 // not the whole path. The idea is that the package name should
aoqi@0 450 // provide enough clue on which directory it lives.
aoqi@0 451 CompilationUnitTree compilationUnit = treePath.getCompilationUnit();
aoqi@0 452 Trees trees = Trees.instance(env);
aoqi@0 453 long startPosition = trees.getSourcePositions().getStartPosition(compilationUnit, treePath.getLeaf());
aoqi@0 454 return name + "(" +
aoqi@0 455 compilationUnit.getSourceFile().getName() + ":" + compilationUnit.getLineMap().getLineNumber(startPosition) +
aoqi@0 456 ")";
aoqi@0 457 }
aoqi@0 458 };
aoqi@0 459 }
aoqi@0 460
aoqi@0 461 /**
aoqi@0 462 * Implements {@link #getBaseClass}.
aoqi@0 463 */
aoqi@0 464 private final SimpleTypeVisitor6<TypeMirror, TypeElement> baseClassFinder = new SimpleTypeVisitor6<TypeMirror, TypeElement>() {
aoqi@0 465 @Override
aoqi@0 466 public TypeMirror visitDeclared(DeclaredType t, TypeElement sup) {
aoqi@0 467 if (t.asElement().equals(sup))
aoqi@0 468 return t;
aoqi@0 469
aoqi@0 470 for (TypeMirror i : env.getTypeUtils().directSupertypes(t)) {
aoqi@0 471 TypeMirror r = visitDeclared((DeclaredType) i, sup);
aoqi@0 472 if (r != null)
aoqi@0 473 return r;
aoqi@0 474 }
aoqi@0 475
aoqi@0 476 // otherwise recursively apply super class and base types
aoqi@0 477 TypeMirror superclass = ((TypeElement) t.asElement()).getSuperclass();
aoqi@0 478 if (!superclass.getKind().equals(TypeKind.NONE)) {
aoqi@0 479 TypeMirror r = visitDeclared((DeclaredType) superclass, sup);
aoqi@0 480 if (r != null)
aoqi@0 481 return r;
aoqi@0 482 }
aoqi@0 483 return null;
aoqi@0 484 }
aoqi@0 485
aoqi@0 486 @Override
aoqi@0 487 public TypeMirror visitTypeVariable(TypeVariable t, TypeElement typeElement) {
aoqi@0 488 // we are checking if T (declared as T extends A&B&C) is assignable to sup.
aoqi@0 489 // so apply bounds recursively.
aoqi@0 490 for (TypeMirror typeMirror : ((TypeParameterElement) t.asElement()).getBounds()) {
aoqi@0 491 TypeMirror m = visit(typeMirror, typeElement);
aoqi@0 492 if (m != null)
aoqi@0 493 return m;
aoqi@0 494 }
aoqi@0 495 return null;
aoqi@0 496 }
aoqi@0 497
aoqi@0 498 @Override
aoqi@0 499 public TypeMirror visitArray(ArrayType t, TypeElement typeElement) {
aoqi@0 500 // we are checking if t=T[] is assignable to sup.
aoqi@0 501 // the only case this is allowed is sup=Object,
aoqi@0 502 // and Object isn't parameterized.
aoqi@0 503 return null;
aoqi@0 504 }
aoqi@0 505
aoqi@0 506 @Override
aoqi@0 507 public TypeMirror visitWildcard(WildcardType t, TypeElement typeElement) {
aoqi@0 508 // we are checking if T (= ? extends A&B&C) is assignable to sup.
aoqi@0 509 // so apply bounds recursively.
aoqi@0 510 return visit(t.getExtendsBound(), typeElement);
aoqi@0 511 }
aoqi@0 512
aoqi@0 513 @Override
aoqi@0 514 protected TypeMirror defaultAction(TypeMirror e, TypeElement typeElement) {
aoqi@0 515 return e;
aoqi@0 516 }
aoqi@0 517 };
aoqi@0 518 }

mercurial