1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package signature.converter.doclet; 18 19 import java.util.EnumSet; 20 import java.util.HashMap; 21 import java.util.HashSet; 22 import java.util.LinkedList; 23 import java.util.List; 24 import java.util.Map; 25 import java.util.Set; 26 import java.util.Stack; 27 import java.util.Map.Entry; 28 29 import signature.converter.Visibility; 30 import signature.model.IAnnotation; 31 import signature.model.IAnnotationElement; 32 import signature.model.IAnnotationField; 33 import signature.model.IApi; 34 import signature.model.IClassDefinition; 35 import signature.model.IClassReference; 36 import signature.model.IConstructor; 37 import signature.model.IEnumConstant; 38 import signature.model.IField; 39 import signature.model.IGenericDeclaration; 40 import signature.model.IMethod; 41 import signature.model.IPackage; 42 import signature.model.IParameter; 43 import signature.model.ITypeReference; 44 import signature.model.ITypeVariableDefinition; 45 import signature.model.ITypeVariableReference; 46 import signature.model.Kind; 47 import signature.model.Modifier; 48 import signature.model.impl.SigAnnotation; 49 import signature.model.impl.SigAnnotationElement; 50 import signature.model.impl.SigAnnotationField; 51 import signature.model.impl.SigApi; 52 import signature.model.impl.SigClassDefinition; 53 import signature.model.impl.SigClassReference; 54 import signature.model.impl.SigConstructor; 55 import signature.model.impl.SigEnumConstant; 56 import signature.model.impl.SigExecutableMember; 57 import signature.model.impl.SigField; 58 import signature.model.impl.SigMethod; 59 import signature.model.impl.SigPackage; 60 import signature.model.impl.SigParameter; 61 import signature.model.impl.SigPrimitiveType; 62 import signature.model.impl.SigTypeVariableDefinition; 63 import signature.model.impl.SigTypeVariableReference; 64 import signature.model.util.TypePool; 65 66 import com.sun.javadoc.AnnotationDesc; 67 import com.sun.javadoc.AnnotationTypeDoc; 68 import com.sun.javadoc.AnnotationTypeElementDoc; 69 import com.sun.javadoc.AnnotationValue; 70 import com.sun.javadoc.ClassDoc; 71 import com.sun.javadoc.ConstructorDoc; 72 import com.sun.javadoc.ExecutableMemberDoc; 73 import com.sun.javadoc.FieldDoc; 74 import com.sun.javadoc.MethodDoc; 75 import com.sun.javadoc.PackageDoc; 76 import com.sun.javadoc.Parameter; 77 import com.sun.javadoc.ParameterizedType; 78 import com.sun.javadoc.ProgramElementDoc; 79 import com.sun.javadoc.RootDoc; 80 import com.sun.javadoc.Type; 81 import com.sun.javadoc.TypeVariable; 82 import com.sun.javadoc.WildcardType; 83 import com.sun.javadoc.AnnotationDesc.ElementValuePair; 84 85 public class DocletToSigConverter { 86 87 TypePool pool; 88 Set<String> packageNames; 89 90 /** 91 * Converts the signature information javadoc knows about into a 92 * signature.model.ISources structure. 93 */ convertDocletRoot(String name, RootDoc root, Visibility visibility, Set<String> packageNames)94 public IApi convertDocletRoot(String name, RootDoc root, 95 Visibility visibility, Set<String> packageNames) { 96 this.pool = new TypePool(); 97 this.packageNames = packageNames; 98 99 Set<IPackage> packages = new HashSet<IPackage>(); 100 101 for (PackageDoc pack : root.specifiedPackages()) { 102 assert packageNames.contains(pack.name()); 103 packages.add(convertPackage(pack)); 104 } 105 106 SigApi sources = new SigApi(name, visibility); 107 sources.setPackages(packages); 108 return sources; 109 } 110 convertPackage(PackageDoc packageDoc)111 private IPackage convertPackage(PackageDoc packageDoc) { 112 Set<IClassDefinition> classes = new HashSet<IClassDefinition>(); 113 for (ClassDoc clazz : packageDoc.allClasses()) { 114 // classes.add((IClass)convertType(clazz)); 115 classes.add(convertClass(clazz)); 116 } 117 118 SigPackage p = new SigPackage(packageDoc.name()); 119 p.setClasses(classes); 120 p.setAnnotations(convertAnnotations(packageDoc.annotations())); 121 return p; 122 } 123 convertClass(ClassDoc classDoc)124 private SigClassDefinition convertClass(ClassDoc classDoc) { 125 126 SigClassDefinition c = pool.getClass(classDoc.containingPackage() 127 .name(), classDoc.name()); 128 if (c.getKind() != Kind.UNINITIALIZED) return c; 129 130 if (classDoc.isEnum()) 131 c.setKind(Kind.ENUM); 132 else if (classDoc.isInterface()) 133 c.setKind(Kind.INTERFACE); 134 else if (classDoc.isClass()) 135 c.setKind(Kind.CLASS); 136 else if (classDoc.isAnnotationType()) c.setKind(Kind.ANNOTATION); 137 138 if (!packageNames.contains(c.getPackageName())) { 139 // no additional conversion for this class is necessary 140 initializeClass(c); 141 return c; 142 } 143 144 c.setModifiers(convertModifiers(classDoc.modifierSpecifier())); 145 if (Kind.INTERFACE.equals(c.getKind()) 146 || Kind.ANNOTATION.equals(c.getKind())) { 147 c.getModifiers().add(Modifier.ABSTRACT); 148 } 149 150 // superclass may be a class or a parameterized type (e.g. extends 151 // List<String>), 152 // may also be null if classDoc is an interface 153 Type superclassType = classDoc.superclassType(); 154 if (superclassType != null) { 155 c.setSuperClass(convertTypeReference(classDoc.superclassType())); 156 } else { 157 c.setSuperClass(null); 158 } 159 160 Set<ITypeReference> interfaces = new HashSet<ITypeReference>(); 161 for (Type interfaceType : classDoc.interfaceTypes()) { 162 interfaces.add(convertTypeReference(interfaceType)); 163 } 164 c.setInterfaces(interfaces); 165 166 ClassDoc containingClass = classDoc.containingClass(); 167 if (containingClass != null) 168 c.setDeclaringClass(convertClass(containingClass)); 169 else 170 c.setDeclaringClass(null); 171 172 Set<IClassDefinition> innerClasses = new HashSet<IClassDefinition>(); 173 for (ClassDoc innerClass : classDoc.innerClasses()) { 174 innerClasses.add(convertClass(innerClass)); 175 } 176 c.setInnerClasses(innerClasses); 177 178 Set<IConstructor> constructors = new HashSet<IConstructor>(); 179 for (ConstructorDoc constructor : classDoc.constructors()) { 180 constructors.add(convertConstructor(constructor)); 181 } 182 c.setConstructors(constructors); 183 184 Set<IMethod> methods = new HashSet<IMethod>(); 185 for (MethodDoc method : classDoc.methods()) { 186 methods.add(convertMethod(method)); 187 } 188 c.setMethods(methods); 189 190 Set<IField> fields = new HashSet<IField>(); 191 for (FieldDoc field : classDoc.fields()) { 192 fields.add(convertField(field)); 193 } 194 c.setFields(fields); 195 196 Set<IEnumConstant> enumConstants = new HashSet<IEnumConstant>(); 197 int ordinal = 0; 198 for (FieldDoc enumConstant : classDoc.enumConstants()) { 199 enumConstants.add(convertEnumConstant(enumConstant, ordinal++)); 200 } 201 c.setEnumConstants(enumConstants); 202 203 List<ITypeVariableDefinition> typeParameters = 204 new LinkedList<ITypeVariableDefinition>(); 205 for (TypeVariable typeVariable : classDoc.typeParameters()) { 206 typeParameters 207 .add(((ITypeVariableReference) convertTypeReference( 208 typeVariable)).getTypeVariableDefinition()); 209 } 210 c.setTypeParameters(typeParameters); 211 212 if (classDoc.isAnnotationType()) { 213 Map<SigAnnotationField, AnnotationTypeElementDoc> annotationFieldAnnotations = 214 new HashMap<SigAnnotationField, AnnotationTypeElementDoc>(); 215 216 // AnnotationTypeDoc annotationType = 217 // classDoc.asAnnotationTypeDoc(); // bug in Doclet Implementation, 218 // has been reported to sun 219 AnnotationTypeDoc annotationType = (AnnotationTypeDoc) classDoc; 220 221 Set<IAnnotationField> annotationFields = 222 new HashSet<IAnnotationField>(); 223 for (AnnotationTypeElementDoc annotationElement : annotationType 224 .elements()) { 225 SigAnnotationField annotationField = new SigAnnotationField( 226 annotationElement.name()); 227 annotationField.setModifiers(convertModifiers(annotationElement 228 .modifierSpecifier())); 229 annotationField.setType(convertTypeReference(annotationElement 230 .returnType())); 231 annotationField 232 .setDefaultValue(convertAnnotationValue( 233 annotationElement.defaultValue())); 234 235 // the annotations on fields are set later because these 236 // annotations may be of 237 // the same type and may use fields which are not yet defined 238 annotationFieldAnnotations.put(annotationField, 239 annotationElement); 240 241 annotationFields.add(annotationField); 242 } 243 c.setAnnotationFields(annotationFields); 244 245 // set annotation field annotations 246 for (Entry<SigAnnotationField, AnnotationTypeElementDoc> entry : 247 annotationFieldAnnotations.entrySet()) { 248 entry.getKey().setAnnotations( 249 convertAnnotations(entry.getValue().annotations())); 250 } 251 } else { // no annotation type 252 c.setAnnotationFields(null); 253 } 254 255 // set class annotations 256 c.setAnnotations(convertAnnotations(classDoc.annotations())); 257 258 return c; 259 260 } 261 convertAnnotationValue(AnnotationValue annotationValue)262 private Object convertAnnotationValue(AnnotationValue annotationValue) { 263 if (annotationValue == null) { 264 return null; 265 } 266 Object value = annotationValue.value(); 267 if (value instanceof Type) { 268 // Type contains primitive types as well, e.g. void.class 269 return convertTypeReference((Type) value); 270 } else if (value instanceof String) { 271 return value; 272 } else if (value instanceof Double || value instanceof Float 273 || value instanceof Long || value instanceof Integer 274 || value instanceof Short || value instanceof Byte 275 || value instanceof Character || value instanceof Boolean) { 276 return value; 277 } else if (value instanceof FieldDoc) { 278 FieldDoc field = (FieldDoc) value; 279 String name = field.name(); 280 ITypeReference fieldType = convertTypeReference(field.type()); 281 IClassReference fieldClassRef = (IClassReference) fieldType; 282 IClassDefinition fieldClass = fieldClassRef.getClassDefinition(); 283 284 assert fieldClass.getKind() == Kind.ENUM; 285 Set<IEnumConstant> constants = fieldClass.getEnumConstants(); 286 for (IEnumConstant enumConstant : constants) { 287 if (enumConstant.getName().equals(name)) value = enumConstant; 288 } 289 assert value instanceof IEnumConstant; 290 return value; 291 } else if (value instanceof AnnotationDesc) { 292 return convertAnnotation((AnnotationDesc) value); 293 } else if (value instanceof AnnotationValue) { 294 return convertAnnotationValue((AnnotationValue) value); 295 } else if (value instanceof AnnotationValue[]) { 296 AnnotationValue[] arr = (AnnotationValue[]) value; 297 int length = arr.length; 298 Object[] annotationArray = new Object[length]; 299 for (int i = 0; i < length; i++) { 300 annotationArray[i] = convertAnnotationValue(arr[i]); 301 } 302 return annotationArray; 303 } else { 304 throw new RuntimeException("not expected case"); 305 } 306 } 307 convertArrayType(Type type)308 private ITypeReference convertArrayType(Type type) { 309 assert type.asWildcardType() == null; 310 assert type.asAnnotationTypeDoc() == null; 311 312 ITypeReference baseType = null; 313 if (type.asTypeVariable() != null) { 314 baseType = convertTypeReference(type.asTypeVariable()); 315 } else if (type.asParameterizedType() != null) { 316 baseType = convertTypeReference(type.asParameterizedType()); 317 } else if (type.asClassDoc() != null) { 318 baseType = new SigClassReference(convertClass(type.asClassDoc())); 319 } else if (type.isPrimitive()) { 320 baseType = SigPrimitiveType.valueOfTypeName(type.typeName()); 321 } else { 322 throw new RuntimeException(type.toString()); 323 } 324 325 ITypeReference arrayType = baseType; 326 int dimension = type.dimension().length() / 2; 327 while (dimension > 0) { 328 arrayType = pool.getArrayType(arrayType); 329 dimension--; 330 } 331 332 return arrayType; 333 } 334 335 private SigTypeVariableDefinition currentTypeVariableDefinition = null; 336 convertTypeReference(Type type)337 private ITypeReference convertTypeReference(Type type) { 338 assert type != null; 339 340 if (!"".equals(type.dimension())) { 341 return convertArrayType(type); 342 } 343 344 ParameterizedType pType = type.asParameterizedType(); 345 if (pType != null) { 346 ITypeReference ownerType = null; 347 Type containingType = pType.containingType(); 348 if (containingType != null) 349 ownerType = convertTypeReference(containingType); 350 IClassReference rawType = new SigClassReference(convertClass(pType 351 .asClassDoc())); 352 353 List<ITypeReference> typeArguments = 354 new LinkedList<ITypeReference>(); 355 for (Type typeArgument : pType.typeArguments()) { 356 typeArguments.add(convertTypeReference(typeArgument)); 357 } 358 359 if (typeArguments.size() > 0) { 360 return pool.getParameterizedType(ownerType, rawType, 361 typeArguments); 362 } else { 363 return rawType; 364 } 365 } 366 367 TypeVariable tv = type.asTypeVariable(); 368 if (tv != null) { 369 String name = tv.typeName(); 370 371 if (currentTypeVariableDefinition != null 372 && name.equals(currentTypeVariableDefinition.getName())) 373 return new SigTypeVariableReference( 374 currentTypeVariableDefinition); 375 376 IGenericDeclaration genericDeclaration = null; 377 ProgramElementDoc programElement = tv.owner(); 378 if (programElement instanceof ClassDoc) { 379 genericDeclaration = convertClass((ClassDoc) programElement); 380 } else if (programElement instanceof MethodDoc 381 && currentMethod.size() > 0) { 382 genericDeclaration = currentMethod.peek(); 383 } else if (programElement instanceof ConstructorDoc 384 && currentConstructor.size() > 0) { 385 genericDeclaration = currentConstructor.peek(); 386 } else { 387 throw new IllegalStateException("situation not expected"); 388 } 389 SigTypeVariableDefinition typeVariable = pool.getTypeVariable(name, 390 genericDeclaration); 391 392 List<ITypeReference> upperBounds = new LinkedList<ITypeReference>(); 393 for (Type upperBound : tv.bounds()) { 394 // we are converting a type variable declaration which is stored 395 // in the 396 // field currentTypeVariableDefinition 397 assert currentTypeVariableDefinition == null; 398 currentTypeVariableDefinition = typeVariable; 399 upperBounds.add(convertTypeReference(upperBound)); 400 currentTypeVariableDefinition = null; 401 } 402 if (upperBounds.size() == 0) { 403 // no explicit bounds, use java.lang.Object 404 upperBounds.add(pool.getClassReference("java.lang", "Object")); 405 } 406 typeVariable.setUpperBounds(upperBounds); 407 408 return new SigTypeVariableReference(typeVariable); 409 } 410 411 WildcardType wt = type.asWildcardType(); 412 if (wt != null) { 413 ITypeReference lowerBound = null; 414 for (Type superBound : wt.superBounds()) { 415 lowerBound = convertTypeReference(superBound); 416 } 417 418 List<ITypeReference> upperBounds = new LinkedList<ITypeReference>(); 419 for (Type upperBound : wt.extendsBounds()) { 420 upperBounds.add(convertTypeReference(upperBound)); 421 } 422 if (upperBounds.size() == 0) { 423 // no explicit bounds, use java.lang.Object 424 upperBounds.add(pool.getClassReference("java.lang", "Object")); 425 } 426 427 return pool.getWildcardType(lowerBound, upperBounds); 428 } 429 430 ClassDoc c = type.asClassDoc(); 431 if (c != null) { 432 return new SigClassReference(convertClass(c)); 433 } 434 435 if (type.isPrimitive()) { 436 return SigPrimitiveType.valueOfTypeName(type.typeName()); 437 } 438 439 throw new IllegalStateException(type.toString()); 440 } 441 convertExecutableMember(ExecutableMemberDoc member, SigExecutableMember m)442 private void convertExecutableMember(ExecutableMemberDoc member, 443 SigExecutableMember m) { 444 Set<Modifier> modifiers = convertModifiers(member.modifierSpecifier()); 445 446 // Doclet Bug: final values method is not considered as final 447 if (member.containingClass().isEnum() && member.name().equals("values") 448 && member.parameters().length == 0) { 449 modifiers.add(Modifier.FINAL); 450 } 451 452 if (member.containingClass().isInterface()) { 453 modifiers.add(Modifier.ABSTRACT); 454 } 455 456 m.setModifiers(modifiers); 457 m.setAnnotations(convertAnnotations(member.annotations())); 458 m.setDeclaringClass(convertClass(member.containingClass())); 459 460 List<ITypeVariableDefinition> typeParameters = 461 new LinkedList<ITypeVariableDefinition>(); 462 for (TypeVariable typeParameter : member.typeParameters()) { 463 String name = typeParameter.typeName(); 464 IGenericDeclaration genericDeclaration = null; 465 if (currentMethod.size() > 0) 466 genericDeclaration = currentMethod.peek(); 467 else if (currentConstructor.size() > 0) 468 genericDeclaration = currentConstructor.peek(); 469 else 470 throw new RuntimeException(); 471 SigTypeVariableDefinition p = pool.getTypeVariable(name, 472 genericDeclaration); 473 474 List<ITypeReference> upperBounds = new LinkedList<ITypeReference>(); 475 for (Type u : typeParameter.bounds()) { 476 upperBounds.add(convertTypeReference(u)); 477 } 478 p.setUpperBounds(upperBounds); 479 typeParameters.add(p); 480 } 481 m.setTypeParameters(typeParameters); 482 483 List<IParameter> parameters = new LinkedList<IParameter>(); 484 for (Parameter parameter : member.parameters()) { 485 SigParameter p = new SigParameter(convertTypeReference(parameter 486 .type())); 487 p.setAnnotations(convertAnnotations(parameter.annotations())); 488 parameters.add(p); 489 } 490 m.setParameters(parameters); 491 492 Set<ITypeReference> exceptions = new HashSet<ITypeReference>(); 493 for (Type exceptionType : member.thrownExceptionTypes()) { 494 exceptions.add(convertTypeReference(exceptionType)); 495 } 496 m.setExceptions(exceptions); 497 } 498 499 private Stack<SigMethod> currentMethod = new Stack<SigMethod>(); 500 convertMethod(MethodDoc method)501 private IMethod convertMethod(MethodDoc method) { 502 SigMethod m = new SigMethod(method.name()); 503 currentMethod.push(m); 504 convertExecutableMember(method, m); 505 m.setReturnType(convertTypeReference(method.returnType())); 506 currentMethod.pop(); 507 return m; 508 } 509 510 private Stack<SigConstructor> currentConstructor = 511 new Stack<SigConstructor>(); 512 convertConstructor(ConstructorDoc constructor)513 private IConstructor convertConstructor(ConstructorDoc constructor) { 514 SigConstructor c = new SigConstructor(constructor.name()); 515 currentConstructor.push(c); 516 convertExecutableMember(constructor, c); 517 currentConstructor.pop(); 518 return c; 519 } 520 convertField(FieldDoc field)521 private IField convertField(FieldDoc field) { 522 SigField f = new SigField(field.name()); 523 f.setAnnotations(convertAnnotations(field.annotations())); 524 f.setModifiers(convertModifiers(field.modifierSpecifier())); 525 f.setType(convertTypeReference(field.type())); 526 return f; 527 } 528 convertEnumConstant(FieldDoc enumConstant, int ordinal)529 private IEnumConstant convertEnumConstant(FieldDoc enumConstant, 530 int ordinal) { 531 SigEnumConstant ec = new SigEnumConstant(enumConstant.name()); 532 ec.setOrdinal(ordinal); 533 ec.setAnnotations(convertAnnotations(enumConstant.annotations())); 534 ec.setModifiers(convertModifiers(enumConstant.modifierSpecifier())); 535 ec.setType(convertTypeReference(enumConstant.type())); 536 return ec; 537 } 538 convertAnnotations( AnnotationDesc[] annotationDescs)539 private Set<IAnnotation> convertAnnotations( 540 AnnotationDesc[] annotationDescs) { 541 Set<IAnnotation> annotations = new HashSet<IAnnotation>(); 542 for (AnnotationDesc annotationDesc : annotationDescs) { 543 if (!annotationRetentionIsSource(annotationDesc)) 544 annotations.add(convertAnnotation(annotationDesc)); 545 } 546 return annotations; 547 } 548 annotationRetentionIsSource(AnnotationDesc annotationDesc)549 private boolean annotationRetentionIsSource(AnnotationDesc annotationDesc) { 550 AnnotationTypeDoc type = annotationDesc.annotationType(); 551 AnnotationDesc[] annotations = type.annotations(); 552 for (AnnotationDesc d : annotations) { 553 if ("java.lang.annotation.Retention".equals(d.annotationType() 554 .qualifiedName())) { 555 for (ElementValuePair value : d.elementValues()) { 556 if ("value".equals(value.element().name())) { 557 return "java.lang.annotation.RetentionPolicy.SOURCE" 558 .equals(value.value().value().toString()); 559 } 560 } 561 } 562 } 563 // default retention policy is CLASS 564 return false; 565 } 566 convertAnnotation(AnnotationDesc annotationDesc)567 private IAnnotation convertAnnotation(AnnotationDesc annotationDesc) { 568 SigAnnotation a = new SigAnnotation(); 569 570 IClassReference annotationType = (IClassReference) convertTypeReference( 571 annotationDesc.annotationType()); 572 a.setType(annotationType); 573 574 Set<IAnnotationElement> elements = new HashSet<IAnnotationElement>(); 575 for (AnnotationDesc.ElementValuePair pair : annotationDesc 576 .elementValues()) { 577 SigAnnotationElement element = new SigAnnotationElement(); 578 elements.add(element); 579 580 element.setValue(convertAnnotationValue(pair.value())); 581 String name = pair.element().name(); 582 for (IAnnotationField field : annotationType.getClassDefinition() 583 .getAnnotationFields()) { 584 if (field.getName().equals(name)) { 585 element.setDeclaringField(field); 586 } 587 } 588 } 589 a.setElements(elements); 590 return a; 591 } 592 initializeClass(SigClassDefinition c)593 private void initializeClass(SigClassDefinition c) { 594 c.setAnnotationFields(null); 595 c.setAnnotations(null); 596 c.setConstructors(null); 597 c.setDeclaringClass(null); 598 c.setEnumConstants(null); 599 c.setFields(null); 600 c.setInnerClasses(null); 601 c.setInterfaces(null); 602 c.setMethods(null); 603 c.setModifiers(null); 604 c.setSuperClass(null); 605 c.setTypeParameters(null); 606 } 607 convertModifiers(int mod)608 private Set<Modifier> convertModifiers(int mod) { 609 Set<Modifier> modifiers = EnumSet.noneOf(Modifier.class); 610 if (java.lang.reflect.Modifier.isAbstract(mod)) 611 modifiers.add(Modifier.ABSTRACT); 612 if (java.lang.reflect.Modifier.isFinal(mod)) 613 modifiers.add(Modifier.FINAL); 614 // if (java.lang.reflect.Modifier.isNative(mod)) 615 // modifiers.add(Modifier.NATIVE); 616 if (java.lang.reflect.Modifier.isPrivate(mod)) 617 modifiers.add(Modifier.PRIVATE); 618 if (java.lang.reflect.Modifier.isProtected(mod)) 619 modifiers.add(Modifier.PROTECTED); 620 if (java.lang.reflect.Modifier.isPublic(mod)) 621 modifiers.add(Modifier.PUBLIC); 622 if (java.lang.reflect.Modifier.isStatic(mod)) 623 modifiers.add(Modifier.STATIC); 624 // if (java.lang.reflect.Modifier.isStrict(mod)) 625 // modifiers.add(Modifier.STRICT); 626 // if (java.lang.reflect.Modifier.isSynchronized(mod)) 627 // modifiers.add(Modifier.SYNCHRONIZED); 628 // if (java.lang.reflect.Modifier.isTransient(mod)) 629 // modifiers.add(Modifier.TRANSIENT); 630 if (java.lang.reflect.Modifier.isVolatile(mod)) 631 modifiers.add(Modifier.VOLATILE); 632 633 return modifiers; 634 } 635 636 } 637