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

Mon, 16 Oct 2017 16:00:54 +0800

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

mercurial