1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/tools/internal/jxc/model/nav/ApNavigator.java Wed Apr 27 01:27:09 2016 +0800 1.3 @@ -0,0 +1,518 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.internal.jxc.model.nav; 1.30 + 1.31 +import com.sun.source.tree.CompilationUnitTree; 1.32 +import com.sun.source.util.TreePath; 1.33 +import com.sun.source.util.Trees; 1.34 +import com.sun.xml.internal.bind.v2.model.nav.Navigator; 1.35 +import com.sun.xml.internal.bind.v2.runtime.Location; 1.36 + 1.37 +import javax.annotation.processing.ProcessingEnvironment; 1.38 +import javax.lang.model.element.AnnotationMirror; 1.39 +import javax.lang.model.element.Element; 1.40 +import javax.lang.model.element.ElementKind; 1.41 +import javax.lang.model.element.ExecutableElement; 1.42 +import javax.lang.model.element.Modifier; 1.43 +import javax.lang.model.element.TypeElement; 1.44 +import javax.lang.model.element.TypeParameterElement; 1.45 +import javax.lang.model.element.VariableElement; 1.46 +import javax.lang.model.type.ArrayType; 1.47 +import javax.lang.model.type.DeclaredType; 1.48 +import javax.lang.model.type.PrimitiveType; 1.49 +import javax.lang.model.type.TypeKind; 1.50 +import javax.lang.model.type.TypeMirror; 1.51 +import javax.lang.model.type.TypeVariable; 1.52 +import javax.lang.model.type.TypeVisitor; 1.53 +import javax.lang.model.type.WildcardType; 1.54 +import javax.lang.model.util.ElementFilter; 1.55 +import javax.lang.model.util.Elements; 1.56 +import javax.lang.model.util.SimpleTypeVisitor6; 1.57 +import javax.lang.model.util.Types; 1.58 +import java.lang.annotation.Annotation; 1.59 +import java.util.Collection; 1.60 +import java.util.HashMap; 1.61 +import java.util.HashSet; 1.62 +import java.util.List; 1.63 +import java.util.Map; 1.64 + 1.65 +/** 1.66 + * {@link Navigator} implementation for annotation processing. 1.67 + * TODO: check the spec on how generics are supposed to be handled 1.68 + * 1.69 + * @author Kohsuke Kawaguchi (kk@kohsuke.org) 1.70 + */ 1.71 +public final class ApNavigator implements Navigator<TypeMirror, TypeElement, VariableElement, ExecutableElement> { 1.72 + 1.73 + private final ProcessingEnvironment env; 1.74 + 1.75 + private final PrimitiveType primitiveByte; 1.76 + 1.77 + public ApNavigator(ProcessingEnvironment env) { 1.78 + this.env = env; 1.79 + this.primitiveByte = env.getTypeUtils().getPrimitiveType(TypeKind.BYTE); 1.80 + } 1.81 + 1.82 + public TypeElement getSuperClass(TypeElement typeElement) { 1.83 + if (typeElement.getKind().equals(ElementKind.CLASS)) { 1.84 + TypeMirror sup = typeElement.getSuperclass(); 1.85 + if (!sup.getKind().equals(TypeKind.NONE)) 1.86 + return (TypeElement) ((DeclaredType) sup).asElement(); 1.87 + else 1.88 + return null; 1.89 + } 1.90 + return env.getElementUtils().getTypeElement(Object.class.getName()); 1.91 + } 1.92 + 1.93 + public TypeMirror getBaseClass(TypeMirror type, TypeElement sup) { 1.94 + return baseClassFinder.visit(type, sup); 1.95 + } 1.96 + 1.97 + public String getClassName(TypeElement t) { 1.98 + return t.getQualifiedName().toString(); 1.99 + } 1.100 + 1.101 + public String getTypeName(TypeMirror typeMirror) { 1.102 + return typeMirror.toString(); 1.103 + } 1.104 + 1.105 + public String getClassShortName(TypeElement t) { 1.106 + return t.getSimpleName().toString(); 1.107 + } 1.108 + 1.109 + public Collection<VariableElement> getDeclaredFields(TypeElement typeElement) { 1.110 + return ElementFilter.fieldsIn(typeElement.getEnclosedElements()); 1.111 + } 1.112 + 1.113 + public VariableElement getDeclaredField(TypeElement clazz, String fieldName) { 1.114 + for (VariableElement fd : ElementFilter.fieldsIn(clazz.getEnclosedElements())) { 1.115 + if (fd.getSimpleName().toString().equals(fieldName)) 1.116 + return fd; 1.117 + } 1.118 + return null; 1.119 + } 1.120 + 1.121 + public Collection<ExecutableElement> getDeclaredMethods(TypeElement typeElement) { 1.122 + return ElementFilter.methodsIn(typeElement.getEnclosedElements()); 1.123 + } 1.124 + 1.125 + public TypeElement getDeclaringClassForField(VariableElement f) { 1.126 + return (TypeElement) f.getEnclosingElement(); 1.127 + } 1.128 + 1.129 + public TypeElement getDeclaringClassForMethod(ExecutableElement m) { 1.130 + return (TypeElement) m.getEnclosingElement(); 1.131 + } 1.132 + 1.133 + public TypeMirror getFieldType(VariableElement f) { 1.134 + return f.asType(); 1.135 + } 1.136 + 1.137 + public String getFieldName(VariableElement f) { 1.138 + return f.getSimpleName().toString(); 1.139 + } 1.140 + 1.141 + public String getMethodName(ExecutableElement m) { 1.142 + return m.getSimpleName().toString(); 1.143 + } 1.144 + 1.145 + public TypeMirror getReturnType(ExecutableElement m) { 1.146 + return m.getReturnType(); 1.147 + } 1.148 + 1.149 + public TypeMirror[] getMethodParameters(ExecutableElement m) { 1.150 + Collection<? extends VariableElement> ps = m.getParameters(); 1.151 + TypeMirror[] r = new TypeMirror[ps.size()]; 1.152 + int i=0; 1.153 + for (VariableElement p : ps) 1.154 + r[i++] = p.asType(); 1.155 + return r; 1.156 + } 1.157 + 1.158 + public boolean isStaticMethod(ExecutableElement m) { 1.159 + return hasModifier(m, Modifier.STATIC); 1.160 + } 1.161 + 1.162 + public boolean isFinalMethod(ExecutableElement m) { 1.163 + return hasModifier(m, Modifier.FINAL); 1.164 + } 1.165 + 1.166 + private boolean hasModifier(Element d, Modifier mod) { 1.167 + return d.getModifiers().contains(mod); 1.168 + } 1.169 + 1.170 + public boolean isSubClassOf(TypeMirror sub, TypeMirror sup) { 1.171 + if(sup==DUMMY) 1.172 + // see ref(). if the sub type is known to Annotation Processing, 1.173 + // its base class must be known. Thus if the sup is DUMMY, 1.174 + // it cannot possibly be the super type. 1.175 + return false; 1.176 + return env.getTypeUtils().isSubtype(sub,sup); 1.177 + } 1.178 + 1.179 + private String getSourceClassName(Class clazz) { 1.180 + Class<?> d = clazz.getDeclaringClass(); 1.181 + if(d==null) 1.182 + return clazz.getName(); 1.183 + else { 1.184 + String shortName = clazz.getName().substring(d.getName().length()+1/*for $*/); 1.185 + return getSourceClassName(d)+'.'+shortName; 1.186 + } 1.187 + } 1.188 + 1.189 + public TypeMirror ref(Class c) { 1.190 + if(c.isArray()) 1.191 + return env.getTypeUtils().getArrayType( ref(c.getComponentType()) ); 1.192 + if(c.isPrimitive()) 1.193 + return getPrimitive(c); 1.194 + TypeElement t = env.getElementUtils().getTypeElement(getSourceClassName(c)); 1.195 + // Annotation Processing only operates on a set of classes used in the compilation, 1.196 + // and it won't recognize additional classes (even if they are visible from javac) 1.197 + // and return null. 1.198 + // 1.199 + // this is causing a problem where we check if a type is collection. 1.200 + // so until the problem is fixed in Annotation Processing, work around the issue 1.201 + // by returning a dummy token 1.202 + // TODO: check if this is still valid 1.203 + if(t==null) 1.204 + return DUMMY; 1.205 + return env.getTypeUtils().getDeclaredType(t); 1.206 + } 1.207 + 1.208 + public TypeMirror use(TypeElement t) { 1.209 + assert t != null; 1.210 + return env.getTypeUtils().getDeclaredType(t); 1.211 + } 1.212 + 1.213 + public TypeElement asDecl(TypeMirror m) { 1.214 + m = env.getTypeUtils().erasure(m); 1.215 + if (m.getKind().equals(TypeKind.DECLARED)) { 1.216 + DeclaredType d = (DeclaredType) m; 1.217 + return (TypeElement) d.asElement(); 1.218 + } else 1.219 + return null; 1.220 + } 1.221 + 1.222 + public TypeElement asDecl(Class c) { 1.223 + return env.getElementUtils().getTypeElement(getSourceClassName(c)); 1.224 + } 1.225 + 1.226 + public TypeMirror erasure(TypeMirror t) { 1.227 + Types tu = env.getTypeUtils(); 1.228 + t = tu.erasure(t); 1.229 + if (t.getKind().equals(TypeKind.DECLARED)) { 1.230 + DeclaredType dt = (DeclaredType)t; 1.231 + if (!dt.getTypeArguments().isEmpty()) 1.232 + return tu.getDeclaredType((TypeElement) dt.asElement()); 1.233 + } 1.234 + return t; 1.235 + } 1.236 + 1.237 + public boolean isAbstract(TypeElement clazz) { 1.238 + return hasModifier(clazz,Modifier.ABSTRACT); 1.239 + } 1.240 + 1.241 + public boolean isFinal(TypeElement clazz) { 1.242 + return hasModifier(clazz, Modifier.FINAL); 1.243 + } 1.244 + 1.245 + public VariableElement[] getEnumConstants(TypeElement clazz) { 1.246 + List<? extends Element> elements = env.getElementUtils().getAllMembers(clazz); 1.247 + Collection<VariableElement> constants = new HashSet<VariableElement>(); 1.248 + for (Element element : elements) { 1.249 + if (element.getKind().equals(ElementKind.ENUM_CONSTANT)) { 1.250 + constants.add((VariableElement) element); 1.251 + } 1.252 + } 1.253 + return constants.toArray(new VariableElement[constants.size()]); 1.254 + } 1.255 + 1.256 + public TypeMirror getVoidType() { 1.257 + return env.getTypeUtils().getNoType(TypeKind.VOID); 1.258 + } 1.259 + 1.260 + public String getPackageName(TypeElement clazz) { 1.261 + return env.getElementUtils().getPackageOf(clazz).getQualifiedName().toString(); 1.262 + } 1.263 + 1.264 + @Override 1.265 + public TypeElement loadObjectFactory(TypeElement referencePoint, String packageName) { 1.266 + return env.getElementUtils().getTypeElement(packageName + ".ObjectFactory"); 1.267 + } 1.268 + 1.269 + public boolean isBridgeMethod(ExecutableElement method) { 1.270 + return method.getModifiers().contains(Modifier.VOLATILE); 1.271 + } 1.272 + 1.273 + public boolean isOverriding(ExecutableElement method, TypeElement base) { 1.274 + Elements elements = env.getElementUtils(); 1.275 + 1.276 + while (true) { 1.277 + for (ExecutableElement m : ElementFilter.methodsIn(elements.getAllMembers(base))) { 1.278 + if (elements.overrides(method, m, base)) 1.279 + return true; 1.280 + } 1.281 + 1.282 + if (base.getSuperclass().getKind().equals(TypeKind.NONE)) 1.283 + return false; 1.284 + base = (TypeElement) env.getTypeUtils().asElement(base.getSuperclass()); 1.285 + } 1.286 + } 1.287 + 1.288 + public boolean isInterface(TypeElement clazz) { 1.289 + return clazz.getKind().isInterface(); 1.290 + } 1.291 + 1.292 + public boolean isTransient(VariableElement f) { 1.293 + return f.getModifiers().contains(Modifier.TRANSIENT); 1.294 + } 1.295 + 1.296 + public boolean isInnerClass(TypeElement clazz) { 1.297 + return clazz.getEnclosingElement() != null && !clazz.getModifiers().contains(Modifier.STATIC); 1.298 + } 1.299 + 1.300 + @Override 1.301 + public boolean isSameType(TypeMirror t1, TypeMirror t2) { 1.302 + return env.getTypeUtils().isSameType(t1, t2); 1.303 + } 1.304 + 1.305 + public boolean isArray(TypeMirror type) { 1.306 + return type != null && type.getKind().equals(TypeKind.ARRAY); 1.307 + } 1.308 + 1.309 + public boolean isArrayButNotByteArray(TypeMirror t) { 1.310 + if(!isArray(t)) 1.311 + return false; 1.312 + 1.313 + ArrayType at = (ArrayType) t; 1.314 + TypeMirror ct = at.getComponentType(); 1.315 + 1.316 + return !ct.equals(primitiveByte); 1.317 + } 1.318 + 1.319 + public TypeMirror getComponentType(TypeMirror t) { 1.320 + if (isArray(t)) { 1.321 + ArrayType at = (ArrayType) t; 1.322 + return at.getComponentType(); 1.323 + } 1.324 + 1.325 + throw new IllegalArgumentException(); 1.326 + } 1.327 + 1.328 + public TypeMirror getTypeArgument(TypeMirror typeMirror, int i) { 1.329 + if (typeMirror != null && typeMirror.getKind().equals(TypeKind.DECLARED)) { 1.330 + DeclaredType declaredType = (DeclaredType) typeMirror; 1.331 + TypeMirror[] args = declaredType.getTypeArguments().toArray(new TypeMirror[declaredType.getTypeArguments().size()]); 1.332 + return args[i]; 1.333 + } else throw new IllegalArgumentException(); 1.334 + } 1.335 + 1.336 + public boolean isParameterizedType(TypeMirror typeMirror) { 1.337 + if (typeMirror != null && typeMirror.getKind().equals(TypeKind.DECLARED)) { 1.338 + DeclaredType d = (DeclaredType) typeMirror; 1.339 + return !d.getTypeArguments().isEmpty(); 1.340 + } 1.341 + return false; 1.342 + } 1.343 + 1.344 + public boolean isPrimitive(TypeMirror t) { 1.345 + return t.getKind().isPrimitive(); 1.346 + } 1.347 + 1.348 + private static final Map<Class, TypeKind> primitives = new HashMap<Class, TypeKind>(); 1.349 + 1.350 + static { 1.351 + primitives.put(Integer.TYPE, TypeKind.INT); 1.352 + primitives.put(Byte.TYPE, TypeKind.BYTE); 1.353 + primitives.put(Float.TYPE, TypeKind.FLOAT); 1.354 + primitives.put(Boolean.TYPE, TypeKind.BOOLEAN); 1.355 + primitives.put(Short.TYPE, TypeKind.SHORT); 1.356 + primitives.put(Long.TYPE, TypeKind.LONG); 1.357 + primitives.put(Double.TYPE, TypeKind.DOUBLE); 1.358 + primitives.put(Character.TYPE, TypeKind.CHAR); 1.359 + } 1.360 + 1.361 + public TypeMirror getPrimitive(Class primitiveType) { 1.362 + assert primitiveType.isPrimitive(); 1.363 + if(primitiveType==void.class) 1.364 + return getVoidType(); 1.365 + return env.getTypeUtils().getPrimitiveType(primitives.get(primitiveType)); 1.366 + } 1.367 + 1.368 + /** 1.369 + * see {@link #ref(Class)}. 1.370 + */ 1.371 + private static final TypeMirror DUMMY = new TypeMirror() { 1.372 + @Override 1.373 + public <R, P> R accept(TypeVisitor<R, P> v, P p) { 1.374 + throw new IllegalStateException(); 1.375 + } 1.376 + 1.377 + @Override 1.378 + public TypeKind getKind() { 1.379 + throw new IllegalStateException(); 1.380 + } 1.381 + 1.382 +// @Override 1.383 + public List<? extends AnnotationMirror> getAnnotationMirrors() { 1.384 + throw new IllegalStateException(); 1.385 + } 1.386 + 1.387 +// @Override 1.388 + public <A extends Annotation> A getAnnotation(Class<A> annotationType) { 1.389 + throw new IllegalStateException(); 1.390 + } 1.391 + 1.392 +// @Override 1.393 + public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) { 1.394 + throw new IllegalStateException(); 1.395 + } 1.396 + }; 1.397 + 1.398 + public Location getClassLocation(TypeElement typeElement) { 1.399 + Trees trees = Trees.instance(env); 1.400 + return getLocation(typeElement.getQualifiedName().toString(), trees.getPath(typeElement)); 1.401 + } 1.402 + 1.403 + public Location getFieldLocation(VariableElement variableElement) { 1.404 + return getLocation(variableElement); 1.405 + } 1.406 + 1.407 + public Location getMethodLocation(ExecutableElement executableElement) { 1.408 + return getLocation(executableElement); 1.409 + } 1.410 + 1.411 + public boolean hasDefaultConstructor(TypeElement t) { 1.412 + if (t == null || !t.getKind().equals(ElementKind.CLASS)) 1.413 + return false; 1.414 + 1.415 + for (ExecutableElement init : ElementFilter.constructorsIn(env.getElementUtils().getAllMembers(t))) { 1.416 + if (init.getParameters().isEmpty()) 1.417 + return true; 1.418 + } 1.419 + return false; 1.420 + } 1.421 + 1.422 + public boolean isStaticField(VariableElement f) { 1.423 + return hasModifier(f,Modifier.STATIC); 1.424 + } 1.425 + 1.426 + public boolean isPublicMethod(ExecutableElement m) { 1.427 + return hasModifier(m,Modifier.PUBLIC); 1.428 + } 1.429 + 1.430 + public boolean isPublicField(VariableElement f) { 1.431 + return hasModifier(f,Modifier.PUBLIC); 1.432 + } 1.433 + 1.434 + public boolean isEnum(TypeElement t) { 1.435 + return t != null && t.getKind().equals(ElementKind.ENUM); 1.436 + } 1.437 + 1.438 + private Location getLocation(Element element) { 1.439 + Trees trees = Trees.instance(env); 1.440 + return getLocation( 1.441 + ((TypeElement) element.getEnclosingElement()).getQualifiedName() + "." + element.getSimpleName(), 1.442 + trees.getPath(element) 1.443 + ); 1.444 + } 1.445 + 1.446 + private Location getLocation(final String name, final TreePath treePath) { 1.447 + return new Location() { 1.448 + public String toString() { 1.449 + if (treePath == null) 1.450 + return name + " (Unknown Source)"; 1.451 + // just like stack trace, we just print the file name and 1.452 + // not the whole path. The idea is that the package name should 1.453 + // provide enough clue on which directory it lives. 1.454 + CompilationUnitTree compilationUnit = treePath.getCompilationUnit(); 1.455 + Trees trees = Trees.instance(env); 1.456 + long startPosition = trees.getSourcePositions().getStartPosition(compilationUnit, treePath.getLeaf()); 1.457 + return name + "(" + 1.458 + compilationUnit.getSourceFile().getName() + ":" + compilationUnit.getLineMap().getLineNumber(startPosition) + 1.459 + ")"; 1.460 + } 1.461 + }; 1.462 + } 1.463 + 1.464 + /** 1.465 + * Implements {@link #getBaseClass}. 1.466 + */ 1.467 + private final SimpleTypeVisitor6<TypeMirror, TypeElement> baseClassFinder = new SimpleTypeVisitor6<TypeMirror, TypeElement>() { 1.468 + @Override 1.469 + public TypeMirror visitDeclared(DeclaredType t, TypeElement sup) { 1.470 + if (t.asElement().equals(sup)) 1.471 + return t; 1.472 + 1.473 + for (TypeMirror i : env.getTypeUtils().directSupertypes(t)) { 1.474 + TypeMirror r = visitDeclared((DeclaredType) i, sup); 1.475 + if (r != null) 1.476 + return r; 1.477 + } 1.478 + 1.479 + // otherwise recursively apply super class and base types 1.480 + TypeMirror superclass = ((TypeElement) t.asElement()).getSuperclass(); 1.481 + if (!superclass.getKind().equals(TypeKind.NONE)) { 1.482 + TypeMirror r = visitDeclared((DeclaredType) superclass, sup); 1.483 + if (r != null) 1.484 + return r; 1.485 + } 1.486 + return null; 1.487 + } 1.488 + 1.489 + @Override 1.490 + public TypeMirror visitTypeVariable(TypeVariable t, TypeElement typeElement) { 1.491 + // we are checking if T (declared as T extends A&B&C) is assignable to sup. 1.492 + // so apply bounds recursively. 1.493 + for (TypeMirror typeMirror : ((TypeParameterElement) t.asElement()).getBounds()) { 1.494 + TypeMirror m = visit(typeMirror, typeElement); 1.495 + if (m != null) 1.496 + return m; 1.497 + } 1.498 + return null; 1.499 + } 1.500 + 1.501 + @Override 1.502 + public TypeMirror visitArray(ArrayType t, TypeElement typeElement) { 1.503 + // we are checking if t=T[] is assignable to sup. 1.504 + // the only case this is allowed is sup=Object, 1.505 + // and Object isn't parameterized. 1.506 + return null; 1.507 + } 1.508 + 1.509 + @Override 1.510 + public TypeMirror visitWildcard(WildcardType t, TypeElement typeElement) { 1.511 + // we are checking if T (= ? extends A&B&C) is assignable to sup. 1.512 + // so apply bounds recursively. 1.513 + return visit(t.getExtendsBound(), typeElement); 1.514 + } 1.515 + 1.516 + @Override 1.517 + protected TypeMirror defaultAction(TypeMirror e, TypeElement typeElement) { 1.518 + return e; 1.519 + } 1.520 + }; 1.521 +}