PageRenderTime 47ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 0ms

/src/com/google/doclava/ClassInfo.java

https://bitbucket.org/fredgrott/androidlava
Java | 2611 lines | 1469 code | 293 blank | 849 comment | 387 complexity | f9de548286a1672da6ad4dd80082fa4d MD5 | raw file
Possible License(s): CC0-1.0
  1. /*
  2. * Copyright (C) 2010 Google Inc.
  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. package com.google.doclava;
  17. import com.google.clearsilver.jsilver.data.Data;
  18. import com.sun.javadoc.ClassDoc;
  19. import java.util.ArrayList;
  20. import java.util.Arrays;
  21. import java.util.Collections;
  22. import java.util.Comparator;
  23. import java.util.HashMap;
  24. import java.util.HashSet;
  25. import java.util.List;
  26. import java.util.Map;
  27. import java.util.Set;
  28. import java.util.TreeMap;
  29. import java.util.TreeSet;
  30. import java.util.Vector;
  31. // TODO: Auto-generated Javadoc
  32. /**
  33. * The Class ClassInfo.
  34. */
  35. @SuppressWarnings("rawtypes")
  36. public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Scoped, Resolvable {
  37. /** The Constant comparator. */
  38. public static final Comparator<ClassInfo> comparator = new Comparator<ClassInfo>() {
  39. public int compare(ClassInfo a, ClassInfo b) {
  40. return a.name().compareTo(b.name());
  41. }
  42. };
  43. /** The Constant qualifiedComparator. */
  44. public static final Comparator<ClassInfo> qualifiedComparator = new Comparator<ClassInfo>() {
  45. public int compare(ClassInfo a, ClassInfo b) {
  46. return a.qualifiedName().compareTo(b.qualifiedName());
  47. }
  48. };
  49. /**
  50. * Constructs a stub representation of a class.
  51. *
  52. * @param qualifiedName the qualified name
  53. */
  54. public ClassInfo(String qualifiedName) {
  55. super("", SourcePositionInfo.UNKNOWN);
  56. mQualifiedName = qualifiedName;
  57. if (qualifiedName.lastIndexOf('.') != -1) {
  58. mName = qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1);
  59. } else {
  60. mName = qualifiedName;
  61. }
  62. }
  63. /**
  64. * Instantiates a new class info.
  65. *
  66. * @param cl the cl
  67. * @param rawCommentText the raw comment text
  68. * @param position the position
  69. * @param isPublic the is public
  70. * @param isProtected the is protected
  71. * @param isPackagePrivate the is package private
  72. * @param isPrivate the is private
  73. * @param isStatic the is static
  74. * @param isInterface the is interface
  75. * @param isAbstract the is abstract
  76. * @param isOrdinaryClass the is ordinary class
  77. * @param isException the is exception
  78. * @param isError the is error
  79. * @param isEnum the is enum
  80. * @param isAnnotation the is annotation
  81. * @param isFinal the is final
  82. * @param isIncluded the is included
  83. * @param name the name
  84. * @param qualifiedName the qualified name
  85. * @param qualifiedTypeName the qualified type name
  86. * @param isPrimitive the is primitive
  87. */
  88. public ClassInfo(ClassDoc cl, String rawCommentText, SourcePositionInfo position,
  89. boolean isPublic, boolean isProtected, boolean isPackagePrivate, boolean isPrivate,
  90. boolean isStatic, boolean isInterface, boolean isAbstract, boolean isOrdinaryClass,
  91. boolean isException, boolean isError, boolean isEnum, boolean isAnnotation, boolean isFinal,
  92. boolean isIncluded, String name, String qualifiedName, String qualifiedTypeName,
  93. boolean isPrimitive) {
  94. super(rawCommentText, position);
  95. initialize(rawCommentText, position,
  96. isPublic, isProtected, isPackagePrivate, isPrivate,
  97. isStatic, isInterface, isAbstract, isOrdinaryClass,
  98. isException, isError, isEnum, isAnnotation, isFinal,
  99. isIncluded, qualifiedTypeName, isPrimitive, null);
  100. mName = name;
  101. mQualifiedName = qualifiedName;
  102. mNameParts = name.split("\\.");
  103. mClass = cl;
  104. }
  105. /**
  106. * Initialize.
  107. *
  108. * @param rawCommentText the raw comment text
  109. * @param position the position
  110. * @param isPublic the is public
  111. * @param isProtected the is protected
  112. * @param isPackagePrivate the is package private
  113. * @param isPrivate the is private
  114. * @param isStatic the is static
  115. * @param isInterface the is interface
  116. * @param isAbstract the is abstract
  117. * @param isOrdinaryClass the is ordinary class
  118. * @param isException the is exception
  119. * @param isError the is error
  120. * @param isEnum the is enum
  121. * @param isAnnotation the is annotation
  122. * @param isFinal the is final
  123. * @param isIncluded the is included
  124. * @param qualifiedTypeName the qualified type name
  125. * @param isPrimitive the is primitive
  126. * @param annotations the annotations
  127. */
  128. public void initialize(String rawCommentText, SourcePositionInfo position,
  129. boolean isPublic, boolean isProtected, boolean isPackagePrivate, boolean isPrivate,
  130. boolean isStatic, boolean isInterface, boolean isAbstract, boolean isOrdinaryClass,
  131. boolean isException, boolean isError, boolean isEnum, boolean isAnnotation, boolean isFinal,
  132. boolean isIncluded, String qualifiedTypeName, boolean isPrimitive, ArrayList<AnnotationInstanceInfo> annotations) {
  133. // calls
  134. setPosition(position);
  135. setRawCommentText(rawCommentText);
  136. mIsPublic = isPublic;
  137. mIsProtected = isProtected;
  138. mIsPackagePrivate = isPackagePrivate;
  139. mIsPrivate = isPrivate;
  140. mIsStatic = isStatic;
  141. mIsInterface = isInterface;
  142. mIsAbstract = isAbstract;
  143. mIsOrdinaryClass = isOrdinaryClass;
  144. mIsException = isException;
  145. mIsError = isError;
  146. mIsEnum = isEnum;
  147. mIsAnnotation = isAnnotation;
  148. mIsFinal = isFinal;
  149. mIsIncluded = isIncluded;
  150. mQualifiedTypeName = qualifiedTypeName;
  151. mIsPrimitive = isPrimitive;
  152. mAnnotations = annotations;
  153. }
  154. /**
  155. * Inits the.
  156. *
  157. * @param typeInfo the type info
  158. * @param interfaces the interfaces
  159. * @param interfaceTypes the interface types
  160. * @param innerClasses the inner classes
  161. * @param constructors the constructors
  162. * @param methods the methods
  163. * @param annotationElements the annotation elements
  164. * @param fields the fields
  165. * @param enumConstants the enum constants
  166. * @param containingPackage the containing package
  167. * @param containingClass the containing class
  168. * @param superclass the superclass
  169. * @param superclassType the superclass type
  170. * @param annotations the annotations
  171. */
  172. public void init(TypeInfo typeInfo, ArrayList<ClassInfo> interfaces,
  173. ArrayList<TypeInfo> interfaceTypes, ArrayList<ClassInfo> innerClasses,
  174. ArrayList<MethodInfo> constructors, ArrayList<MethodInfo> methods,
  175. ArrayList<MethodInfo> annotationElements, ArrayList<FieldInfo> fields,
  176. ArrayList<FieldInfo> enumConstants, PackageInfo containingPackage,
  177. ClassInfo containingClass, ClassInfo superclass,
  178. TypeInfo superclassType, ArrayList<AnnotationInstanceInfo> annotations) {
  179. mTypeInfo = typeInfo;
  180. mRealInterfaces = new ArrayList<ClassInfo>(interfaces);
  181. mRealInterfaceTypes = interfaceTypes;
  182. mInnerClasses = innerClasses;
  183. mAllConstructors = constructors;
  184. mAllSelfMethods = methods;
  185. mAnnotationElements = annotationElements;
  186. mAllSelfFields = fields;
  187. mEnumConstants = enumConstants;
  188. mContainingPackage = containingPackage;
  189. mContainingClass = containingClass;
  190. mRealSuperclass = superclass;
  191. mRealSuperclassType = superclassType;
  192. mAnnotations = annotations;
  193. // after providing new methods and new superclass info,clear any cached
  194. // lists of self + superclass methods, ctors, etc.
  195. mSuperclassInit = false;
  196. mConstructors = null;
  197. mMethods = null;
  198. mSelfMethods = null;
  199. mFields = null;
  200. mSelfFields = null;
  201. mSelfAttributes = null;
  202. mDeprecatedKnown = false;
  203. Collections.sort(mEnumConstants, FieldInfo.comparator);
  204. Collections.sort(mInnerClasses, ClassInfo.comparator);
  205. }
  206. /**
  207. * Init2.
  208. */
  209. public void init2() {
  210. // calling this here forces the AttrTagInfo objects to be linked to the AttribtueInfo
  211. // objects
  212. selfAttributes();
  213. }
  214. /**
  215. * Init3.
  216. *
  217. * @param types the types
  218. * @param realInnerClasses the real inner classes
  219. */
  220. public void init3(ArrayList<TypeInfo> types, ArrayList<ClassInfo> realInnerClasses) {
  221. mTypeParameters = types;
  222. mRealInnerClasses = realInnerClasses;
  223. }
  224. /**
  225. * Gets the real inner classes.
  226. *
  227. * @return the real inner classes
  228. */
  229. public ArrayList<ClassInfo> getRealInnerClasses() {
  230. return mRealInnerClasses;
  231. }
  232. /**
  233. * Gets the type parameters.
  234. *
  235. * @return the type parameters
  236. */
  237. public ArrayList<TypeInfo> getTypeParameters() {
  238. return mTypeParameters;
  239. }
  240. /**
  241. * @see com.google.doclava.ContainerInfo#checkLevel()
  242. */
  243. public boolean checkLevel() {
  244. int val = mCheckLevel;
  245. if (val >= 0) {
  246. return val != 0;
  247. } else {
  248. boolean v =
  249. Doclava.checkLevel(mIsPublic, mIsProtected, mIsPackagePrivate, mIsPrivate, isHidden());
  250. mCheckLevel = v ? 1 : 0;
  251. return v;
  252. }
  253. }
  254. /**
  255. * @see java.lang.Comparable#compareTo(java.lang.Object)
  256. */
  257. public int compareTo(Object that) {
  258. if (that instanceof ClassInfo) {
  259. return mQualifiedName.compareTo(((ClassInfo) that).mQualifiedName);
  260. } else {
  261. return this.hashCode() - that.hashCode();
  262. }
  263. }
  264. /**
  265. * @see com.google.doclava.DocInfo#parent()
  266. */
  267. @Override
  268. public ContainerInfo parent() {
  269. return this;
  270. }
  271. /**
  272. * @see com.google.doclava.Scoped#isPublic()
  273. */
  274. public boolean isPublic() {
  275. return mIsPublic;
  276. }
  277. /**
  278. * @see com.google.doclava.Scoped#isProtected()
  279. */
  280. public boolean isProtected() {
  281. return mIsProtected;
  282. }
  283. /**
  284. * @see com.google.doclava.Scoped#isPackagePrivate()
  285. */
  286. public boolean isPackagePrivate() {
  287. return mIsPackagePrivate;
  288. }
  289. /**
  290. * @see com.google.doclava.Scoped#isPrivate()
  291. */
  292. public boolean isPrivate() {
  293. return mIsPrivate;
  294. }
  295. /**
  296. * Checks if is static.
  297. *
  298. * @return true, if is static
  299. */
  300. public boolean isStatic() {
  301. return mIsStatic;
  302. }
  303. /**
  304. * Checks if is interface.
  305. *
  306. * @return true, if is interface
  307. */
  308. public boolean isInterface() {
  309. return mIsInterface;
  310. }
  311. /**
  312. * Checks if is abstract.
  313. *
  314. * @return true, if is abstract
  315. */
  316. public boolean isAbstract() {
  317. return mIsAbstract;
  318. }
  319. /**
  320. * Containing package.
  321. *
  322. * @return the package info
  323. */
  324. public PackageInfo containingPackage() {
  325. return mContainingPackage;
  326. }
  327. /**
  328. * Containing class.
  329. *
  330. * @return the class info
  331. */
  332. public ClassInfo containingClass() {
  333. return mContainingClass;
  334. }
  335. /**
  336. * Checks if is ordinary class.
  337. *
  338. * @return true, if is ordinary class
  339. */
  340. public boolean isOrdinaryClass() {
  341. return mIsOrdinaryClass;
  342. }
  343. /**
  344. * Checks if is exception.
  345. *
  346. * @return true, if is exception
  347. */
  348. public boolean isException() {
  349. return mIsException;
  350. }
  351. /**
  352. * Checks if is error.
  353. *
  354. * @return true, if is error
  355. */
  356. public boolean isError() {
  357. return mIsError;
  358. }
  359. /**
  360. * Checks if is enum.
  361. *
  362. * @return true, if is enum
  363. */
  364. public boolean isEnum() {
  365. return mIsEnum;
  366. }
  367. /**
  368. * Checks if is annotation.
  369. *
  370. * @return true, if is annotation
  371. */
  372. public boolean isAnnotation() {
  373. return mIsAnnotation;
  374. }
  375. /**
  376. * Checks if is final.
  377. *
  378. * @return true, if is final
  379. */
  380. public boolean isFinal() {
  381. return mIsFinal;
  382. }
  383. /**
  384. * Checks if is included.
  385. *
  386. * @return true, if is included
  387. */
  388. public boolean isIncluded() {
  389. return mIsIncluded;
  390. }
  391. /**
  392. * Type variables.
  393. *
  394. * @return the hash set
  395. */
  396. public HashSet<String> typeVariables() {
  397. HashSet<String> result = TypeInfo.typeVariables(mTypeInfo.typeArguments());
  398. ClassInfo cl = containingClass();
  399. while (cl != null) {
  400. ArrayList<TypeInfo> types = cl.asTypeInfo().typeArguments();
  401. if (types != null) {
  402. TypeInfo.typeVariables(types, result);
  403. }
  404. cl = cl.containingClass();
  405. }
  406. return result;
  407. }
  408. /**
  409. * Gather hidden interfaces.
  410. *
  411. * @param cl the cl
  412. * @param interfaces the interfaces
  413. */
  414. private static void gatherHiddenInterfaces(ClassInfo cl, HashSet<ClassInfo> interfaces) {
  415. for (ClassInfo iface : cl.mRealInterfaces) {
  416. if (iface.checkLevel()) {
  417. interfaces.add(iface);
  418. } else {
  419. gatherHiddenInterfaces(iface, interfaces);
  420. }
  421. }
  422. }
  423. /**
  424. * Interfaces.
  425. *
  426. * @return the array list
  427. */
  428. public ArrayList<ClassInfo> interfaces() {
  429. if (mInterfaces == null) {
  430. if (checkLevel()) {
  431. HashSet<ClassInfo> interfaces = new HashSet<ClassInfo>();
  432. ClassInfo superclass = mRealSuperclass;
  433. while (superclass != null && !superclass.checkLevel()) {
  434. gatherHiddenInterfaces(superclass, interfaces);
  435. superclass = superclass.mRealSuperclass;
  436. }
  437. gatherHiddenInterfaces(this, interfaces);
  438. mInterfaces = new ArrayList<ClassInfo>(interfaces);
  439. } else {
  440. // put something here in case someone uses it
  441. mInterfaces = new ArrayList<ClassInfo>(mRealInterfaces);
  442. }
  443. Collections.sort(mInterfaces, ClassInfo.qualifiedComparator);
  444. }
  445. return mInterfaces;
  446. }
  447. /**
  448. * Real interfaces.
  449. *
  450. * @return the array list
  451. */
  452. public ArrayList<ClassInfo> realInterfaces() {
  453. return mRealInterfaces;
  454. }
  455. /**
  456. * Real interface types.
  457. *
  458. * @return the array list
  459. */
  460. ArrayList<TypeInfo> realInterfaceTypes() {
  461. return mRealInterfaceTypes;
  462. }
  463. /**
  464. * Adds the interface type.
  465. *
  466. * @param type the type
  467. */
  468. public void addInterfaceType(TypeInfo type) {
  469. if (mRealInterfaceTypes == null) {
  470. mRealInterfaceTypes = new ArrayList<TypeInfo>();
  471. }
  472. mRealInterfaceTypes.add(type);
  473. }
  474. /**
  475. * Name.
  476. *
  477. * @return the string
  478. */
  479. public String name() {
  480. return mName;
  481. }
  482. /**
  483. * Name parts.
  484. *
  485. * @return the string[]
  486. */
  487. public String[] nameParts() {
  488. return mNameParts;
  489. }
  490. /**
  491. * Leaf name.
  492. *
  493. * @return the string
  494. */
  495. public String leafName() {
  496. return mNameParts[mNameParts.length - 1];
  497. }
  498. /**
  499. * @see com.google.doclava.ContainerInfo#qualifiedName()
  500. */
  501. public String qualifiedName() {
  502. return mQualifiedName;
  503. }
  504. /**
  505. * Qualified type name.
  506. *
  507. * @return the string
  508. */
  509. public String qualifiedTypeName() {
  510. return mQualifiedTypeName;
  511. }
  512. /**
  513. * Checks if is primitive.
  514. *
  515. * @return true, if is primitive
  516. */
  517. public boolean isPrimitive() {
  518. return mIsPrimitive;
  519. }
  520. /**
  521. * All constructors.
  522. *
  523. * @return the array list
  524. */
  525. public ArrayList<MethodInfo> allConstructors() {
  526. return mAllConstructors;
  527. }
  528. /**
  529. * Constructors.
  530. *
  531. * @return the array list
  532. */
  533. public ArrayList<MethodInfo> constructors() {
  534. if (mConstructors == null) {
  535. if (mAllConstructors == null) {
  536. return new ArrayList<MethodInfo>();
  537. }
  538. mConstructors = new ArrayList<MethodInfo>();
  539. for (MethodInfo m : mAllConstructors) {
  540. if (!m.isHidden()) {
  541. mConstructors.add(m);
  542. }
  543. }
  544. Collections.sort(mConstructors, MethodInfo.comparator);
  545. }
  546. return mConstructors;
  547. }
  548. /**
  549. * Inner classes.
  550. *
  551. * @return the array list
  552. */
  553. public ArrayList<ClassInfo> innerClasses() {
  554. return mInnerClasses;
  555. }
  556. /**
  557. * Inline tags.
  558. *
  559. * @return the tag info[]
  560. */
  561. public TagInfo[] inlineTags() {
  562. return comment().tags();
  563. }
  564. /**
  565. * First sentence tags.
  566. *
  567. * @return the tag info[]
  568. */
  569. public TagInfo[] firstSentenceTags() {
  570. return comment().briefTags();
  571. }
  572. /**
  573. * Sets the deprecated.
  574. *
  575. * @param deprecated the new deprecated
  576. */
  577. public void setDeprecated(boolean deprecated) {
  578. mDeprecatedKnown = true;
  579. mIsDeprecated = deprecated;
  580. }
  581. /**
  582. * Checks if is deprecated.
  583. *
  584. * @return true, if is deprecated
  585. */
  586. public boolean isDeprecated() {
  587. if (!mDeprecatedKnown) {
  588. boolean commentDeprecated = comment().isDeprecated();
  589. boolean annotationDeprecated = false;
  590. for (AnnotationInstanceInfo annotation : annotations()) {
  591. if (annotation.type().qualifiedName().equals("java.lang.Deprecated")) {
  592. annotationDeprecated = true;
  593. break;
  594. }
  595. }
  596. if (commentDeprecated != annotationDeprecated) {
  597. Errors.error(Errors.DEPRECATION_MISMATCH, position(), "Class " + qualifiedName()
  598. + ": @Deprecated annotation and @deprecated comment do not match");
  599. }
  600. mIsDeprecated = commentDeprecated | annotationDeprecated;
  601. mDeprecatedKnown = true;
  602. }
  603. return mIsDeprecated;
  604. }
  605. /**
  606. * Deprecated tags.
  607. *
  608. * @return the tag info[]
  609. */
  610. public TagInfo[] deprecatedTags() {
  611. // Should we also do the interfaces?
  612. return comment().deprecatedTags();
  613. }
  614. /**
  615. * Methods.
  616. *
  617. * @return the array list
  618. */
  619. public ArrayList<MethodInfo> methods() {
  620. if (mMethods == null) {
  621. TreeMap<String, MethodInfo> all = new TreeMap<String, MethodInfo>();
  622. ArrayList<ClassInfo> interfaces = interfaces();
  623. for (ClassInfo iface : interfaces) {
  624. if (iface != null) {
  625. for (MethodInfo method : iface.methods()) {
  626. all.put(method.getHashableName(), method);
  627. }
  628. }
  629. }
  630. ClassInfo superclass = superclass();
  631. if (superclass != null) {
  632. for (MethodInfo method : superclass.methods()) {
  633. all.put(method.getHashableName(), method);
  634. }
  635. }
  636. for (MethodInfo method : selfMethods()) {
  637. all.put(method.getHashableName(), method);
  638. }
  639. mMethods = new ArrayList<MethodInfo>(all.values());
  640. Collections.sort(mMethods, MethodInfo.comparator);
  641. }
  642. return mMethods;
  643. }
  644. /**
  645. * Annotation elements.
  646. *
  647. * @return the array list
  648. */
  649. public ArrayList<MethodInfo> annotationElements() {
  650. return mAnnotationElements;
  651. }
  652. /**
  653. * Annotations.
  654. *
  655. * @return the array list
  656. */
  657. public ArrayList<AnnotationInstanceInfo> annotations() {
  658. return mAnnotations;
  659. }
  660. /**
  661. * Adds the fields.
  662. *
  663. * @param cl the cl
  664. * @param all the all
  665. */
  666. private static void addFields(ClassInfo cl, TreeMap<String, FieldInfo> all) {
  667. for (FieldInfo field : cl.fields()) {
  668. all.put(field.name(), field);
  669. }
  670. }
  671. /**
  672. * Fields.
  673. *
  674. * @return the array list
  675. */
  676. public ArrayList<FieldInfo> fields() {
  677. if (mFields == null) {
  678. TreeMap<String, FieldInfo> all = new TreeMap<String, FieldInfo>();
  679. for (ClassInfo iface : interfaces()) {
  680. addFields(iface, all);
  681. }
  682. ClassInfo superclass = superclass();
  683. if (superclass != null) {
  684. addFields(superclass, all);
  685. }
  686. for (FieldInfo field : selfFields()) {
  687. if (!field.isHidden()) {
  688. all.put(field.name(), field);
  689. }
  690. }
  691. mFields = new ArrayList<FieldInfo>(all.values());
  692. }
  693. return mFields;
  694. }
  695. /**
  696. * Gather fields.
  697. *
  698. * @param owner the owner
  699. * @param cl the cl
  700. * @param fields the fields
  701. */
  702. public void gatherFields(ClassInfo owner, ClassInfo cl, HashMap<String, FieldInfo> fields) {
  703. for (FieldInfo f : cl.selfFields()) {
  704. if (f.checkLevel()) {
  705. fields.put(f.name(), f.cloneForClass(owner));
  706. }
  707. }
  708. }
  709. /**
  710. * Self fields.
  711. *
  712. * @return the array list
  713. */
  714. public ArrayList<FieldInfo> selfFields() {
  715. if (mSelfFields == null) {
  716. HashMap<String, FieldInfo> fields = new HashMap<String, FieldInfo>();
  717. // our hidden parents
  718. if (mRealSuperclass != null && !mRealSuperclass.checkLevel()) {
  719. gatherFields(this, mRealSuperclass, fields);
  720. }
  721. for (ClassInfo iface : mRealInterfaces) {
  722. if (!iface.checkLevel()) {
  723. gatherFields(this, iface, fields);
  724. }
  725. }
  726. for (FieldInfo f : mAllSelfFields) {
  727. if (!f.isHidden()) {
  728. fields.put(f.name(), f);
  729. }
  730. }
  731. mSelfFields = new ArrayList<FieldInfo>(fields.values());
  732. Collections.sort(mSelfFields, FieldInfo.comparator);
  733. }
  734. return mSelfFields;
  735. }
  736. /**
  737. * All self fields.
  738. *
  739. * @return the array list
  740. */
  741. public ArrayList<FieldInfo> allSelfFields() {
  742. return mAllSelfFields;
  743. }
  744. /**
  745. * Gather methods.
  746. *
  747. * @param owner the owner
  748. * @param cl the cl
  749. * @param methods the methods
  750. */
  751. private void gatherMethods(ClassInfo owner, ClassInfo cl, HashMap<String, MethodInfo> methods) {
  752. for (MethodInfo m : cl.selfMethods()) {
  753. if (m.checkLevel()) {
  754. methods.put(m.name() + m.signature(), m.cloneForClass(owner));
  755. }
  756. }
  757. }
  758. /**
  759. * Self methods.
  760. *
  761. * @return the array list
  762. */
  763. public ArrayList<MethodInfo> selfMethods() {
  764. if (mSelfMethods == null) {
  765. HashMap<String, MethodInfo> methods = new HashMap<String, MethodInfo>();
  766. // our hidden parents
  767. if (mRealSuperclass != null && !mRealSuperclass.checkLevel()) {
  768. gatherMethods(this, mRealSuperclass, methods);
  769. }
  770. for (ClassInfo iface : mRealInterfaces) {
  771. if (!iface.checkLevel()) {
  772. gatherMethods(this, iface, methods);
  773. }
  774. }
  775. // mine
  776. if (mAllSelfMethods != null) {
  777. for (MethodInfo m : mAllSelfMethods) {
  778. if (m.checkLevel()) {
  779. methods.put(m.name() + m.signature(), m);
  780. }
  781. }
  782. }
  783. // sort it
  784. mSelfMethods = new ArrayList<MethodInfo>(methods.values());
  785. Collections.sort(mSelfMethods, MethodInfo.comparator);
  786. }
  787. return mSelfMethods;
  788. }
  789. /**
  790. * All self methods.
  791. *
  792. * @return the array list
  793. */
  794. public ArrayList<MethodInfo> allSelfMethods() {
  795. return mAllSelfMethods;
  796. }
  797. /**
  798. * Adds the method.
  799. *
  800. * @param method the method
  801. */
  802. public void addMethod(MethodInfo method) {
  803. mApiCheckMethods.put(method.getHashableName(), method);
  804. mAllSelfMethods.add(method);
  805. mSelfMethods = null; // flush this, hopefully it hasn't been used yet.
  806. }
  807. /**
  808. * Adds the annotation element.
  809. *
  810. * @param method the method
  811. */
  812. public void addAnnotationElement(MethodInfo method) {
  813. mAnnotationElements.add(method);
  814. }
  815. /**
  816. * Sets the containing package.
  817. *
  818. * @param pkg the new containing package
  819. */
  820. public void setContainingPackage(PackageInfo pkg) {
  821. mContainingPackage = pkg;
  822. if (mContainingPackage != null) {
  823. if (mIsEnum) {
  824. mContainingPackage.addEnum(this);
  825. } else if (mIsInterface) {
  826. mContainingPackage.addInterface(this);
  827. } else {
  828. mContainingPackage.addOrdinaryClass(this);
  829. }
  830. }
  831. }
  832. /**
  833. * Self attributes.
  834. *
  835. * @return the array list
  836. */
  837. public ArrayList<AttributeInfo> selfAttributes() {
  838. if (mSelfAttributes == null) {
  839. TreeMap<FieldInfo, AttributeInfo> attrs = new TreeMap<FieldInfo, AttributeInfo>();
  840. // the ones in the class comment won't have any methods
  841. for (AttrTagInfo tag : comment().attrTags()) {
  842. FieldInfo field = tag.reference();
  843. if (field != null) {
  844. AttributeInfo attr = attrs.get(field);
  845. if (attr == null) {
  846. attr = new AttributeInfo(this, field);
  847. attrs.put(field, attr);
  848. }
  849. tag.setAttribute(attr);
  850. }
  851. }
  852. // in the methods
  853. for (MethodInfo m : selfMethods()) {
  854. for (AttrTagInfo tag : m.comment().attrTags()) {
  855. FieldInfo field = tag.reference();
  856. if (field != null) {
  857. AttributeInfo attr = attrs.get(field);
  858. if (attr == null) {
  859. attr = new AttributeInfo(this, field);
  860. attrs.put(field, attr);
  861. }
  862. tag.setAttribute(attr);
  863. attr.methods.add(m);
  864. }
  865. }
  866. }
  867. // constructors too
  868. for (MethodInfo m : constructors()) {
  869. for (AttrTagInfo tag : m.comment().attrTags()) {
  870. FieldInfo field = tag.reference();
  871. if (field != null) {
  872. AttributeInfo attr = attrs.get(field);
  873. if (attr == null) {
  874. attr = new AttributeInfo(this, field);
  875. attrs.put(field, attr);
  876. }
  877. tag.setAttribute(attr);
  878. attr.methods.add(m);
  879. }
  880. }
  881. }
  882. mSelfAttributes = new ArrayList<AttributeInfo>(attrs.values());
  883. Collections.sort(mSelfAttributes, AttributeInfo.comparator);
  884. }
  885. return mSelfAttributes;
  886. }
  887. /**
  888. * Enum constants.
  889. *
  890. * @return the array list
  891. */
  892. public ArrayList<FieldInfo> enumConstants() {
  893. return mEnumConstants;
  894. }
  895. /**
  896. * Superclass.
  897. *
  898. * @return the class info
  899. */
  900. public ClassInfo superclass() {
  901. if (!mSuperclassInit) {
  902. if (this.checkLevel()) {
  903. // rearrange our little inheritance hierarchy, because we need to hide classes that
  904. // don't pass checkLevel
  905. ClassInfo superclass = mRealSuperclass;
  906. while (superclass != null && !superclass.checkLevel()) {
  907. superclass = superclass.mRealSuperclass;
  908. }
  909. mSuperclass = superclass;
  910. } else {
  911. mSuperclass = mRealSuperclass;
  912. }
  913. }
  914. return mSuperclass;
  915. }
  916. /**
  917. * Real superclass.
  918. *
  919. * @return the class info
  920. */
  921. public ClassInfo realSuperclass() {
  922. return mRealSuperclass;
  923. }
  924. /**
  925. * always the real superclass, not the collapsed one we get through
  926. * superclass(), also has the type parameter info if it's generic.
  927. *
  928. * @return the type info
  929. */
  930. public TypeInfo superclassType() {
  931. return mRealSuperclassType;
  932. }
  933. /**
  934. * As type info.
  935. *
  936. * @return the type info
  937. */
  938. public TypeInfo asTypeInfo() {
  939. return mTypeInfo;
  940. }
  941. /**
  942. * Interface types.
  943. *
  944. * @return the array list
  945. */
  946. ArrayList<TypeInfo> interfaceTypes() {
  947. ArrayList<TypeInfo> types = new ArrayList<TypeInfo>();
  948. for (ClassInfo iface : interfaces()) {
  949. types.add(iface.asTypeInfo());
  950. }
  951. return types;
  952. }
  953. /**
  954. * @see com.google.doclava.DocInfo#htmlPage()
  955. */
  956. public String htmlPage() {
  957. String s = containingPackage().name();
  958. s = s.replace('.', '/');
  959. s += '/';
  960. s += name();
  961. s += ".html";
  962. s = Doclava.javadocDir + s;
  963. return s;
  964. }
  965. /**
  966. * Even indirectly.
  967. *
  968. * @param cl the cl
  969. * @return true, if is derived from
  970. */
  971. public boolean isDerivedFrom(ClassInfo cl) {
  972. return isDerivedFrom(cl.qualifiedName());
  973. }
  974. /**
  975. * Even indirectly.
  976. *
  977. * @param qualifiedName the qualified name
  978. * @return true, if is derived from
  979. */
  980. public boolean isDerivedFrom(String qualifiedName) {
  981. ClassInfo dad = this.superclass();
  982. if (dad != null) {
  983. if (dad.mQualifiedName.equals(qualifiedName)) {
  984. return true;
  985. } else {
  986. if (dad.isDerivedFrom(qualifiedName)) {
  987. return true;
  988. }
  989. }
  990. }
  991. for (ClassInfo iface : interfaces()) {
  992. if (iface.mQualifiedName.equals(qualifiedName)) {
  993. return true;
  994. } else {
  995. if (iface.isDerivedFrom(qualifiedName)) {
  996. return true;
  997. }
  998. }
  999. }
  1000. return false;
  1001. }
  1002. /**
  1003. * Make keyword entries.
  1004. *
  1005. * @param keywords the keywords
  1006. */
  1007. public void makeKeywordEntries(List<KeywordEntry> keywords) {
  1008. if (!checkLevel()) {
  1009. return;
  1010. }
  1011. String htmlPage = htmlPage();
  1012. String qualifiedName = qualifiedName();
  1013. keywords.add(new KeywordEntry(name(), htmlPage, "class in " + containingPackage().name()));
  1014. ArrayList<FieldInfo> fields = selfFields();
  1015. //ArrayList<FieldInfo> enumConstants = enumConstants();
  1016. ArrayList<MethodInfo> ctors = constructors();
  1017. ArrayList<MethodInfo> methods = selfMethods();
  1018. // enum constants
  1019. for (FieldInfo field : enumConstants()) {
  1020. if (field.checkLevel()) {
  1021. keywords.add(new KeywordEntry(field.name(), htmlPage + "#" + field.anchor(),
  1022. "enum constant in " + qualifiedName));
  1023. }
  1024. }
  1025. // constants
  1026. for (FieldInfo field : fields) {
  1027. if (field.isConstant() && field.checkLevel()) {
  1028. keywords.add(new KeywordEntry(field.name(), htmlPage + "#" + field.anchor(), "constant in "
  1029. + qualifiedName));
  1030. }
  1031. }
  1032. // fields
  1033. for (FieldInfo field : fields) {
  1034. if (!field.isConstant() && field.checkLevel()) {
  1035. keywords.add(new KeywordEntry(field.name(), htmlPage + "#" + field.anchor(), "field in "
  1036. + qualifiedName));
  1037. }
  1038. }
  1039. // public constructors
  1040. for (MethodInfo m : ctors) {
  1041. if (m.isPublic() && m.checkLevel()) {
  1042. keywords.add(new KeywordEntry(m.prettySignature(), htmlPage + "#" + m.anchor(),
  1043. "constructor in " + qualifiedName));
  1044. }
  1045. }
  1046. // protected constructors
  1047. if (Doclava.checkLevel(Doclava.SHOW_PROTECTED)) {
  1048. for (MethodInfo m : ctors) {
  1049. if (m.isProtected() && m.checkLevel()) {
  1050. keywords.add(new KeywordEntry(m.prettySignature(),
  1051. htmlPage + "#" + m.anchor(), "constructor in " + qualifiedName));
  1052. }
  1053. }
  1054. }
  1055. // package private constructors
  1056. if (Doclava.checkLevel(Doclava.SHOW_PACKAGE)) {
  1057. for (MethodInfo m : ctors) {
  1058. if (m.isPackagePrivate() && m.checkLevel()) {
  1059. keywords.add(new KeywordEntry(m.prettySignature(),
  1060. htmlPage + "#" + m.anchor(), "constructor in " + qualifiedName));
  1061. }
  1062. }
  1063. }
  1064. // private constructors
  1065. if (Doclava.checkLevel(Doclava.SHOW_PRIVATE)) {
  1066. for (MethodInfo m : ctors) {
  1067. if (m.isPrivate() && m.checkLevel()) {
  1068. keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
  1069. htmlPage + "#" + m.anchor(), "constructor in " + qualifiedName));
  1070. }
  1071. }
  1072. }
  1073. // public methods
  1074. for (MethodInfo m : methods) {
  1075. if (m.isPublic() && m.checkLevel()) {
  1076. keywords.add(new KeywordEntry(m.name() + m.prettySignature(), htmlPage + "#" + m.anchor(),
  1077. "method in " + qualifiedName));
  1078. }
  1079. }
  1080. // protected methods
  1081. if (Doclava.checkLevel(Doclava.SHOW_PROTECTED)) {
  1082. for (MethodInfo m : methods) {
  1083. if (m.isProtected() && m.checkLevel()) {
  1084. keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
  1085. htmlPage + "#" + m.anchor(), "method in " + qualifiedName));
  1086. }
  1087. }
  1088. }
  1089. // package private methods
  1090. if (Doclava.checkLevel(Doclava.SHOW_PACKAGE)) {
  1091. for (MethodInfo m : methods) {
  1092. if (m.isPackagePrivate() && m.checkLevel()) {
  1093. keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
  1094. htmlPage + "#" + m.anchor(), "method in " + qualifiedName));
  1095. }
  1096. }
  1097. }
  1098. // private methods
  1099. if (Doclava.checkLevel(Doclava.SHOW_PRIVATE)) {
  1100. for (MethodInfo m : methods) {
  1101. if (m.isPrivate() && m.checkLevel()) {
  1102. keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
  1103. htmlPage + "#" + m.anchor(), "method in " + qualifiedName));
  1104. }
  1105. }
  1106. }
  1107. }
  1108. /**
  1109. * Make link.
  1110. *
  1111. * @param data the data
  1112. * @param base the base
  1113. */
  1114. public void makeLink(Data data, String base) {
  1115. data.setValue(base + ".label", this.name());
  1116. if (!this.isPrimitive() && this.isIncluded() && this.checkLevel()) {
  1117. data.setValue(base + ".link", this.htmlPage());
  1118. }
  1119. }
  1120. /**
  1121. * Make link list hdf.
  1122. *
  1123. * @param data the data
  1124. * @param base the base
  1125. * @param classes the classes
  1126. */
  1127. public static void makeLinkListHDF(Data data, String base, ClassInfo[] classes) {
  1128. final int N = classes.length;
  1129. for (int i = 0; i < N; i++) {
  1130. ClassInfo cl = classes[i];
  1131. if (cl.checkLevel()) {
  1132. cl.asTypeInfo().makeHDF(data, base + "." + i);
  1133. }
  1134. }
  1135. }
  1136. /**
  1137. * Used in lists of this class (packages, nested classes, known subclasses).
  1138. *
  1139. * @param data the data
  1140. * @param base the base
  1141. */
  1142. public void makeShortDescrHDF(Data data, String base) {
  1143. mTypeInfo.makeHDF(data, base + ".type");
  1144. data.setValue(base + ".kind", this.kind());
  1145. TagInfo.makeHDF(data, base + ".shortDescr", this.firstSentenceTags());
  1146. TagInfo.makeHDF(data, base + ".deprecated", deprecatedTags());
  1147. data.setValue(base + ".since", getSince());
  1148. if (isDeprecated()) {
  1149. data.setValue(base + ".deprecatedsince", getDeprecatedSince());
  1150. }
  1151. setFederatedReferences(data, base);
  1152. }
  1153. /**
  1154. * Turns into the main class page.
  1155. *
  1156. * @param data the data
  1157. */
  1158. public void makeHDF(Data data) {
  1159. int i, j, n;
  1160. String name = name();
  1161. String qualified = qualifiedName();
  1162. ArrayList<AttributeInfo> selfAttributes = selfAttributes();
  1163. ArrayList<MethodInfo> methods = selfMethods();
  1164. ArrayList<FieldInfo> fields = selfFields();
  1165. ArrayList<FieldInfo> enumConstants = enumConstants();
  1166. ArrayList<MethodInfo> ctors = constructors();
  1167. ArrayList<ClassInfo> inners = innerClasses();
  1168. // class name
  1169. mTypeInfo.makeHDF(data, "class.type");
  1170. mTypeInfo.makeQualifiedHDF(data, "class.qualifiedType");
  1171. data.setValue("class.name", name);
  1172. data.setValue("class.qualified", qualified);
  1173. if (isProtected()) {
  1174. data.setValue("class.scope", "protected");
  1175. } else if (isPublic()) {
  1176. data.setValue("class.scope", "public");
  1177. }
  1178. if (isStatic()) {
  1179. data.setValue("class.static", "static");
  1180. }
  1181. if (isFinal()) {
  1182. data.setValue("class.final", "final");
  1183. }
  1184. if (isAbstract() && !isInterface()) {
  1185. data.setValue("class.abstract", "abstract");
  1186. }
  1187. // class info
  1188. String kind = kind();
  1189. if (kind != null) {
  1190. data.setValue("class.kind", kind);
  1191. }
  1192. data.setValue("class.since", getSince());
  1193. if (isDeprecated()) {
  1194. data.setValue("class.deprecatedsince", getDeprecatedSince());
  1195. }
  1196. setFederatedReferences(data, "class");
  1197. // the containing package -- note that this can be passed to type_link,
  1198. // but it also contains the list of all of the packages
  1199. containingPackage().makeClassLinkListHDF(data, "class.package");
  1200. // inheritance hierarchy
  1201. Vector<ClassInfo> superClasses = new Vector<ClassInfo>();
  1202. superClasses.add(this);
  1203. ClassInfo supr = superclass();
  1204. while (supr != null) {
  1205. superClasses.add(supr);
  1206. supr = supr.superclass();
  1207. }
  1208. n = superClasses.size();
  1209. for (i = 0; i < n; i++) {
  1210. supr = superClasses.elementAt(n - i - 1);
  1211. supr.asTypeInfo().makeQualifiedHDF(data, "class.inheritance." + i + ".class");
  1212. supr.asTypeInfo().makeHDF(data, "class.inheritance." + i + ".short_class");
  1213. j = 0;
  1214. for (TypeInfo t : supr.interfaceTypes()) {
  1215. t.makeHDF(data, "class.inheritance." + i + ".interfaces." + j);
  1216. j++;
  1217. }
  1218. }
  1219. // class description
  1220. TagInfo.makeHDF(data, "class.descr", inlineTags());
  1221. TagInfo.makeHDF(data, "class.seeAlso", comment().seeTags());
  1222. TagInfo.makeHDF(data, "class.deprecated", deprecatedTags());
  1223. // known subclasses
  1224. TreeMap<String, ClassInfo> direct = new TreeMap<String, ClassInfo>();
  1225. TreeMap<String, ClassInfo> indirect = new TreeMap<String, ClassInfo>();
  1226. ClassInfo[] all = Converter.rootClasses();
  1227. for (ClassInfo cl : all) {
  1228. if (cl.superclass() != null && cl.superclass().equals(this)) {
  1229. direct.put(cl.name(), cl);
  1230. } else if (cl.isDerivedFrom(this)) {
  1231. indirect.put(cl.name(), cl);
  1232. }
  1233. }
  1234. // direct
  1235. i = 0;
  1236. for (ClassInfo cl : direct.values()) {
  1237. if (cl.checkLevel()) {
  1238. cl.makeShortDescrHDF(data, "class.subclasses.direct." + i);
  1239. }
  1240. i++;
  1241. }
  1242. // indirect
  1243. i = 0;
  1244. for (ClassInfo cl : indirect.values()) {
  1245. if (cl.checkLevel()) {
  1246. cl.makeShortDescrHDF(data, "class.subclasses.indirect." + i);
  1247. }
  1248. i++;
  1249. }
  1250. // hide special cases
  1251. if ("java.lang.Object".equals(qualified) || "java.io.Serializable".equals(qualified)) {
  1252. data.setValue("class.subclasses.hidden", "1");
  1253. } else {
  1254. data.setValue("class.subclasses.hidden", "0");
  1255. }
  1256. // nested classes
  1257. i = 0;
  1258. for (ClassInfo inner : inners) {
  1259. if (inner.checkLevel()) {
  1260. inner.makeShortDescrHDF(data, "class.inners." + i);
  1261. }
  1262. i++;
  1263. }
  1264. // enum constants
  1265. i = 0;
  1266. for (FieldInfo field : enumConstants) {
  1267. field.makeHDF(data, "class.enumConstants." + i);
  1268. i++;
  1269. }
  1270. // constants
  1271. i = 0;
  1272. for (FieldInfo field : fields) {
  1273. if (field.isConstant()) {
  1274. field.makeHDF(data, "class.constants." + i);
  1275. i++;
  1276. }
  1277. }
  1278. // fields
  1279. i = 0;
  1280. for (FieldInfo field : fields) {
  1281. if (!field.isConstant()) {
  1282. field.makeHDF(data, "class.fields." + i);
  1283. i++;
  1284. }
  1285. }
  1286. // public constructors
  1287. i = 0;
  1288. for (MethodInfo ctor : ctors) {
  1289. if (ctor.isPublic()) {
  1290. ctor.makeHDF(data, "class.ctors.public." + i);
  1291. i++;
  1292. }
  1293. }
  1294. // protected constructors
  1295. if (Doclava.checkLevel(Doclava.SHOW_PROTECTED)) {
  1296. i = 0;
  1297. for (MethodInfo ctor : ctors) {
  1298. if (ctor.isProtected()) {
  1299. ctor.makeHDF(data, "class.ctors.protected." + i);
  1300. i++;
  1301. }
  1302. }
  1303. }
  1304. // package private constructors
  1305. if (Doclava.checkLevel(Doclava.SHOW_PACKAGE)) {
  1306. i = 0;
  1307. for (MethodInfo ctor : ctors) {
  1308. if (ctor.isPackagePrivate()) {
  1309. ctor.makeHDF(data, "class.ctors.package." + i);
  1310. i++;
  1311. }
  1312. }
  1313. }
  1314. // private constructors
  1315. if (Doclava.checkLevel(Doclava.SHOW_PRIVATE)) {
  1316. i = 0;
  1317. for (MethodInfo ctor : ctors) {
  1318. if (ctor.isPrivate()) {
  1319. ctor.makeHDF(data, "class.ctors.private." + i);
  1320. i++;
  1321. }
  1322. }
  1323. }
  1324. // public methods
  1325. i = 0;
  1326. for (MethodInfo method : methods) {
  1327. if (method.isPublic()) {
  1328. method.makeHDF(data, "class.methods.public." + i);
  1329. i++;
  1330. }
  1331. }
  1332. // protected methods
  1333. if (Doclava.checkLevel(Doclava.SHOW_PROTECTED)) {
  1334. i = 0;
  1335. for (MethodInfo method : methods) {
  1336. if (method.isProtected()) {
  1337. method.makeHDF(data, "class.methods.protected." + i);
  1338. i++;
  1339. }
  1340. }
  1341. }
  1342. // package private methods
  1343. if (Doclava.checkLevel(Doclava.SHOW_PACKAGE)) {
  1344. i = 0;
  1345. for (MethodInfo method : methods) {
  1346. if (method.isPackagePrivate()) {
  1347. method.makeHDF(data, "class.methods.package." + i);
  1348. i++;
  1349. }
  1350. }
  1351. }
  1352. // private methods
  1353. if (Doclava.checkLevel(Doclava.SHOW_PRIVATE)) {
  1354. i = 0;
  1355. for (MethodInfo method : methods) {
  1356. if (method.isPrivate()) {
  1357. method.makeHDF(data, "class.methods.private." + i);
  1358. i++;
  1359. }
  1360. }
  1361. }
  1362. // xml attributes
  1363. i = 0;
  1364. for (AttributeInfo attr : selfAttributes) {
  1365. if (attr.checkLevel()) {
  1366. attr.makeHDF(data, "class.attrs." + i);
  1367. i++;
  1368. }
  1369. }
  1370. // inherited methods
  1371. Set<ClassInfo> interfaces = new TreeSet<ClassInfo>();
  1372. addInterfaces(interfaces(), interfaces);
  1373. ClassInfo cl = superclass();
  1374. i = 0;
  1375. while (cl != null) {
  1376. addInterfaces(cl.interfaces(), interfaces);
  1377. makeInheritedHDF(data, i, cl);
  1378. cl = cl.superclass();
  1379. i++;
  1380. }
  1381. for (ClassInfo iface : interfaces) {
  1382. makeInheritedHDF(data, i, iface);
  1383. i++;
  1384. }
  1385. }
  1386. /**
  1387. * Adds the interfaces.
  1388. *
  1389. * @param ifaces the ifaces
  1390. * @param out the out
  1391. */
  1392. private static void addInterfaces(ArrayList<ClassInfo> ifaces, Set<ClassInfo> out) {
  1393. for (ClassInfo cl : ifaces) {
  1394. out.add(cl);
  1395. addInterfaces(cl.interfaces(), out);
  1396. }
  1397. }
  1398. /**
  1399. * Make inherited hdf.
  1400. *
  1401. * @param data the data
  1402. * @param index the index
  1403. * @param cl the cl
  1404. */
  1405. private static void makeInheritedHDF(Data data, int index, ClassInfo cl) {
  1406. int i;
  1407. String base = "class.inherited." + index;
  1408. data.setValue(base + ".qualified", cl.qualifiedName());
  1409. if (cl.checkLevel()) {
  1410. data.setValue(base + ".link", cl.htmlPage());
  1411. }
  1412. String kind = cl.kind();
  1413. if (kind != null) {
  1414. data.setValue(base + ".kind", kind);
  1415. }
  1416. if (cl.mIsIncluded) {
  1417. data.setValue(base + ".included", "true");
  1418. } else {
  1419. Doclava.federationTagger.tagAll(new ClassInfo[] {cl});
  1420. if (!cl.getFederatedReferences().isEmpty()) {
  1421. FederatedSite site = cl.getFederatedReferences().iterator().next();
  1422. data.setValue(base + ".link", site.linkFor(cl.htmlPage()));
  1423. data.setValue(base + ".federated", site.name());
  1424. }
  1425. }
  1426. // xml attributes
  1427. i = 0;
  1428. for (AttributeInfo attr : cl.selfAttributes()) {
  1429. attr.makeHDF(data, base + ".attrs." + i);
  1430. i++;
  1431. }
  1432. // methods
  1433. i = 0;
  1434. for (MethodInfo method : cl.selfMethods()) {
  1435. method.makeHDF(data, base + ".methods." + i);
  1436. i++;
  1437. }
  1438. // fields
  1439. i = 0;
  1440. for (FieldInfo field : cl.selfFields()) {
  1441. if (!field.isConstant()) {
  1442. field.makeHDF(data, base + ".fields." + i);
  1443. i++;
  1444. }
  1445. }
  1446. // constants
  1447. i = 0;
  1448. for (FieldInfo field : cl.selfFields()) {
  1449. if (field.isConstant()) {
  1450. field.makeHDF(data, base + ".constants." + i);
  1451. i++;
  1452. }
  1453. }
  1454. }
  1455. /**
  1456. * @see com.google.doclava.DocInfo#isHidden()
  1457. */
  1458. @Override
  1459. public boolean isHidden() {
  1460. int val = mHidden;
  1461. if (val >= 0) {
  1462. return val != 0;
  1463. } else {
  1464. boolean v = isHiddenImpl();
  1465. mHidden = v ? 1 : 0;
  1466. return v;
  1467. }
  1468. }
  1469. /**
  1470. * Checks if is hidden impl.
  1471. *
  1472. * @return true, if is hidden impl
  1473. */
  1474. public boolean isHiddenImpl() {
  1475. ClassInfo cl = this;
  1476. while (cl != null) {
  1477. PackageInfo pkg = cl.containingPackage();
  1478. if (pkg != null && pkg.isHidden()) {
  1479. return true;
  1480. }
  1481. if (cl.comment().isHidden()) {
  1482. return true;
  1483. }
  1484. cl = cl.containingClass();
  1485. }
  1486. return false;
  1487. }
  1488. /**
  1489. * Match method.
  1490. *
  1491. * @param methods the methods
  1492. * @param name the name
  1493. * @param params the params
  1494. * @param dimensions the dimensions
  1495. * @param varargs the varargs
  1496. * @return the method info
  1497. */
  1498. private MethodInfo matchMethod(ArrayList<MethodInfo> methods, String name, String[] params,
  1499. String[] dimensions, boolean varargs) {
  1500. for (MethodInfo method : methods) {
  1501. if (method.name().equals(name)) {
  1502. if (params == null) {
  1503. return method;
  1504. } else {
  1505. if (method.matchesParams(params, dimensions, varargs)) {
  1506. return method;
  1507. }
  1508. }
  1509. }
  1510. }
  1511. return null;
  1512. }
  1513. /**
  1514. * Find method.
  1515. *
  1516. * @param name the name
  1517. * @param params the params
  1518. * @param dimensions the dimensions
  1519. * @param varargs the varargs
  1520. * @return the method info
  1521. */
  1522. public MethodInfo findMethod(String name, String[] params, String[] dimensions, boolean varargs) {
  1523. // first look on our class, and our superclasses
  1524. // for methods
  1525. MethodInfo rv;
  1526. rv = matchMethod(methods(), name, params, dimensions, varargs);
  1527. if (rv != null) {
  1528. return rv;
  1529. }
  1530. // for constructors
  1531. rv = matchMethod(constructors(), name, params, dimensions, varargs);
  1532. if (rv != null) {
  1533. return rv;
  1534. }
  1535. // then recursively look at our containing class
  1536. ClassInfo containing = containingClass();
  1537. if (containing != null) {
  1538. return containing.findMethod(name, params, dimensions, varargs);
  1539. }
  1540. return null;
  1541. }
  1542. /**
  1543. * Supports method.
  1544. *
  1545. * @param method the method
  1546. * @return true, if successful
  1547. */
  1548. public boolean supportsMethod(MethodInfo method) {
  1549. for (MethodInfo m : methods()) {
  1550. if (m.getHashableName().equals(method.getHashableName())) {
  1551. return true;
  1552. }
  1553. }
  1554. return false;
  1555. }
  1556. /**
  1557. * Search inner classes.
  1558. *
  1559. * @param nameParts the name parts
  1560. * @param index the index
  1561. * @return the class info
  1562. */
  1563. private ClassInfo searchInnerClasses(String[] nameParts, int index) {
  1564. String part = nameParts[index];
  1565. ArrayList<ClassInfo> inners = mInnerClasses;
  1566. for (ClassInfo in : inners) {
  1567. String[] innerParts = in.nameParts();
  1568. if (part.equals(innerParts[innerParts.length - 1])) {
  1569. if (index == nameParts.length - 1) {
  1570. return in;
  1571. } else {
  1572. return in.searchInnerClasses(nameParts, index + 1);
  1573. }
  1574. }
  1575. }
  1576. return null;
  1577. }
  1578. /**
  1579. * Extended find class.
  1580. *
  1581. * @param className the class name
  1582. * @return the class info
  1583. */
  1584. public ClassInfo extendedFindClass(String className) {
  1585. // ClassDoc.findClass has this bug that we're working around here:
  1586. // If you have a class PackageManager with an inner class PackageInfo
  1587. // and you call it with "PackageInfo" it doesn't find it.
  1588. return searchInnerClasses(className.split("\\."), 0);
  1589. }
  1590. /**
  1591. * Find class.
  1592. *
  1593. * @param className the class name
  1594. * @return the class info
  1595. */
  1596. public ClassInfo findClass(String className) {
  1597. return Converter.obtainClass(mClass.findClass(className));
  1598. }
  1599. /**
  1600. * Find inner class.
  1601. *
  1602. * @param className the class name
  1603. * @return the class info
  1604. */
  1605. public ClassInfo findInnerClass(String className) {
  1606. // ClassDoc.findClass won't find inner classes. To deal with that,
  1607. // we try what they gave us first, but if that didn't work, then
  1608. // we see if there are any periods in className, and start searching
  1609. // from there.
  1610. String[] nodes = className.split("\\.");
  1611. ClassDoc cl = mClass;
  1612. for (String n : nodes) {
  1613. cl = cl.findClass(n);
  1614. if (cl == null) {
  1615. return null;
  1616. }
  1617. }
  1618. return Converter.obtainClass(cl);
  1619. }
  1620. /**
  1621. * Find field.
  1622. *
  1623. * @param name the name
  1624. * @return the field info
  1625. */
  1626. public FieldInfo findField(String name) {
  1627. // first look on our class, and our superclasses
  1628. for (FieldInfo f : fields()) {
  1629. if (f.name().equals(name)) {
  1630. return f;
  1631. }
  1632. }
  1633. // then look at our enum constants (these are really fields, maybe
  1634. // they should be mixed into fields(). not sure)
  1635. for (FieldInfo f : enumConstants()) {
  1636. if (f.name().equals(name)) {
  1637. return f;
  1638. }
  1639. }
  1640. // then recursively look at our containing class
  1641. ClassInfo containing = containingClass();
  1642. if (containing != null) {
  1643. return containing.findField(name);
  1644. }
  1645. return null;
  1646. }
  1647. /**
  1648. * Sort by name.
  1649. *
  1650. * @param classes the classes
  1651. * @return the class info[]
  1652. */
  1653. public static ClassInfo[] sortByName(ClassInfo[] classes) {
  1654. int i;
  1655. Sorter[] sorted = new Sorter[classes.length];
  1656. for (i = 0; i < sorted.length; i++) {
  1657. ClassInfo cl = classes[i];
  1658. sorted[i] = new Sorter(cl.name(), cl);
  1659. }
  1660. Arrays.sort(sorted);
  1661. ClassInfo[] rv = new ClassInfo[classes.length];
  1662. for (i = 0; i < rv.length; i++) {
  1663. rv[i] = (ClassInfo) sorted[i].data;
  1664. }
  1665. return rv;
  1666. }
  1667. /**
  1668. * Equals.
  1669. *
  1670. * @param that the that
  1671. * @return true, if successful
  1672. */
  1673. public boolean equals(ClassInfo that) {
  1674. if (that != null) {
  1675. return this.qualifiedName().equals(that.qualifiedName());
  1676. } else {
  1677. return false;
  1678. }
  1679. }
  1680. /**
  1681. * Sets the non written constructors.
  1682. *
  1683. * @param nonWritten the new non written constructors
  1684. */
  1685. public void setNonWrittenConstructors(ArrayList<MethodInfo> nonWritten) {
  1686. mNonWrittenConstructors = nonWritten;
  1687. }
  1688. /**
  1689. * Gets the non written constructors.
  1690. *
  1691. * @return the non written constructors
  1692. */
  1693. public ArrayList<MethodInfo> getNonWrittenConstructors() {
  1694. return mNonWrittenConstructors;
  1695. }
  1696. /**
  1697. * Kind.
  1698. *
  1699. * @return the string
  1700. */
  1701. public String kind() {
  1702. if (isOrdinaryClass()) {
  1703. return "class";
  1704. } else if (isInterface()) {
  1705. return "interface";
  1706. } else if (isEnum()) {
  1707. return "enum";
  1708. } else if (isError()) {
  1709. return "class";
  1710. } else if (isException()) {
  1711. return "class";
  1712. } else if (isAnnotation()) {
  1713. return "@interface";
  1714. }
  1715. return null;
  1716. }
  1717. /**
  1718. * Scope.
  1719. *
  1720. * @return the string
  1721. */
  1722. public String scope() {
  1723. if (isPublic()) {
  1724. return "public";
  1725. } else if (isProtected()) {
  1726. return "protected";
  1727. } else if (isPackagePrivate()) {
  1728. return "";
  1729. } else if (isPrivate()) {
  1730. return "private";
  1731. } else {
  1732. throw new RuntimeException("invalid scope for object " + this);
  1733. }
  1734. }
  1735. /**
  1736. * Sets the hidden methods.
  1737. *
  1738. * @param mInfo the new hidden methods
  1739. */
  1740. public void setHiddenMethods(ArrayList<MethodInfo> mInfo) {
  1741. mHiddenMethods = mInfo;
  1742. }
  1743. /**
  1744. * Gets the hidden methods.
  1745. *
  1746. * @return the hidden methods
  1747. */
  1748. public ArrayList<MethodInfo> getHiddenMethods() {
  1749. return mHiddenMethods;
  1750. }
  1751. /**
  1752. * @see java.lang.Object#toString()
  1753. */
  1754. @Override
  1755. public String toString() {
  1756. return this.qualifiedName();
  1757. }
  1758. /**
  1759. * Sets the reason included.
  1760. *
  1761. * @param reason the new reason included
  1762. */
  1763. public void setReasonIncluded(String reason) {
  1764. mReasonIncluded = reason;
  1765. }
  1766. /**
  1767. * Gets the reason included.
  1768. *
  1769. * @return the reason included
  1770. */
  1771. public String getReasonIncluded() {
  1772. return mReasonIncluded;
  1773. }
  1774. /** The m class. */
  1775. private ClassDoc mClass;
  1776. // ctor
  1777. /** The m is public. */
  1778. private boolean mIsPublic;
  1779. /** The m is protected. */
  1780. private boolean mIsProtected;
  1781. /** The m is package private. */
  1782. private boolean mIsPackagePrivate;
  1783. /** The m is private. */
  1784. private boolean mIsPrivate;
  1785. /** The m is static. */
  1786. private boolean mIsStatic;
  1787. /** The m is interface. */
  1788. private boolean mIsInterface;
  1789. /** The m is abstract. */
  1790. private boolean mIsAbstract;
  1791. /** The m is ordinary class. */
  1792. private boolean mIsOrdinaryClass;
  1793. /** The m is exception. */
  1794. private boolean mIsException;
  1795. /** The m is error. */
  1796. private boolean mIsError;
  1797. /** The m is enum. */
  1798. private boolean mIsEnum;
  1799. /** The m is annotation. */
  1800. private boolean mIsAnnotation;
  1801. /** The m is final. */
  1802. private boolean mIsFinal;
  1803. /** The m is included. */
  1804. private boolean mIsIncluded;
  1805. /** The m name. */
  1806. private String mName;
  1807. /** The m qualified name. */
  1808. private String mQualifiedName;
  1809. /** The m qualified type name. */
  1810. private String mQualifiedTypeName;
  1811. /** The m is primitive. */
  1812. private boolean mIsPrimitive;
  1813. /** The m type info. */
  1814. private TypeInfo mTypeInfo;
  1815. /** The m name parts. */
  1816. private String[] mNameParts;
  1817. // init
  1818. /** The m real interfaces. */
  1819. private ArrayList<ClassInfo> mRealInterfaces = new ArrayList<ClassInfo>();
  1820. /** The m interfaces. */
  1821. private ArrayList<ClassInfo> mInterfaces;
  1822. /** The m real interface types. */
  1823. private ArrayList<TypeInfo> mRealInterfaceTypes;
  1824. /** The m inner classes. */
  1825. private ArrayList<ClassInfo> mInnerClasses;
  1826. /** The m all constructors. */
  1827. private ArrayList<MethodInfo> mAllConstructors = new ArrayList<MethodInfo>();
  1828. /** The m all self methods. */
  1829. private ArrayList<MethodInfo> mAllSelfMethods = new ArrayList<MethodInfo>();
  1830. /** The m annotation elements. */
  1831. private ArrayList<MethodInfo> mAnnotationElements = new ArrayList<MethodInfo>(); // if this class is an annotation
  1832. /** The m all self fields. */
  1833. private ArrayList<FieldInfo> mAllSelfFields = new ArrayList<FieldInfo>();
  1834. /** The m enum constants. */
  1835. private ArrayList<FieldInfo> mEnumConstants = new ArrayList<FieldInfo>();
  1836. /** The m containing package. */
  1837. private PackageInfo mContainingPackage;
  1838. /** The m containing class. */
  1839. private ClassInfo mContainingClass;
  1840. /** The m real superclass. */
  1841. private ClassInfo mRealSuperclass;
  1842. /** The m real superclass type. */
  1843. private TypeInfo mRealSuperclassType;
  1844. /** The m superclass. */
  1845. private ClassInfo mSuperclass;
  1846. /** The m annotations. */
  1847. private ArrayList<AnnotationInstanceInfo> mAnnotations;
  1848. /** The m superclass init. */
  1849. private boolean mSuperclassInit;
  1850. /** The m deprecated known. */
  1851. private boolean mDeprecatedKnown;
  1852. // lazy
  1853. /** The m constructors. */
  1854. private ArrayList<MethodInfo> mConstructors;
  1855. /** The m real inner classes. */
  1856. private ArrayList<ClassInfo> mRealInnerClasses;
  1857. /** The m self methods. */
  1858. private ArrayList<MethodInfo> mSelfMethods;
  1859. /** The m self fields. */
  1860. private ArrayList<FieldInfo> mSelfFields;
  1861. /** The m self attributes. */
  1862. private ArrayList<AttributeInfo> mSelfAttributes;
  1863. /** The m methods. */
  1864. private ArrayList<MethodInfo> mMethods;
  1865. /** The m fields. */
  1866. private ArrayList<FieldInfo> mFields;
  1867. /** The m type parameters. */
  1868. private ArrayList<TypeInfo> mTypeParameters;
  1869. /** The m hidden methods. */
  1870. private ArrayList<MethodInfo> mHiddenMethods;
  1871. /** The m hidden. */
  1872. private int mHidden = -1;
  1873. /** The m check level. */
  1874. private int mCheckLevel = -1;
  1875. /** The m reason included. */
  1876. private String mReasonIncluded;
  1877. /** The m non written constructors. */
  1878. private ArrayList<MethodInfo> mNonWrittenConstructors;
  1879. /** The m is deprecated. */
  1880. private boolean mIsDeprecated;
  1881. // TODO: Temporary members from apicheck migration.
  1882. /** The m api check constructors. */
  1883. private HashMap<String, MethodInfo> mApiCheckConstructors = new HashMap<String, MethodInfo>();
  1884. /** The m api check methods. */
  1885. private HashMap<String, MethodInfo> mApiCheckMethods = new HashMap<String, MethodInfo>();
  1886. /** The m api check fields. */
  1887. private HashMap<String, FieldInfo> mApiCheckFields = new HashMap<String, FieldInfo>();
  1888. /** The m api check enum constants. */
  1889. private HashMap<String, FieldInfo> mApiCheckEnumConstants = new HashMap<String, FieldInfo>();
  1890. // Resolutions
  1891. /** The m resolutions. */
  1892. private ArrayList<Resolution> mResolutions;
  1893. /**
  1894. * Returns true if {@code cl} implements the interface {@code iface} either
  1895. * by either being that interface, implementing that interface or extending
  1896. * a type that implements the interface.
  1897. *
  1898. * @param cl the cl
  1899. * @param iface the iface
  1900. * @return true, if successful
  1901. */
  1902. private boolean implementsInterface(ClassInfo cl, String iface) {
  1903. if (cl.qualifiedName().equals(iface)) {
  1904. return true;
  1905. }
  1906. for (ClassInfo clImplements : cl.interfaces()) {
  1907. if (implementsInterface(clImplements, iface)) {
  1908. return true;
  1909. }
  1910. }
  1911. if (cl.mSuperclass != null && implementsInterface(cl.mSuperclass, iface)) {
  1912. return true;
  1913. }
  1914. return false;
  1915. }
  1916. /**
  1917. * Adds the interface.
  1918. *
  1919. * @param iface the iface
  1920. */
  1921. public void addInterface(ClassInfo iface) {
  1922. mRealInterfaces.add(iface);
  1923. }
  1924. /**
  1925. * Adds the constructor.
  1926. *
  1927. * @param ctor the ctor
  1928. */
  1929. public void addConstructor(MethodInfo ctor) {
  1930. mApiCheckConstructors.put(ctor.getHashableName(), ctor);
  1931. mAllConstructors.add(ctor);
  1932. mConstructors = null; // flush this, hopefully it hasn't been used yet.
  1933. }
  1934. /**
  1935. * Adds the field.
  1936. *
  1937. * @param field the field
  1938. */
  1939. public void addField(FieldInfo field) {
  1940. mApiCheckFields.put(field.name(), field);
  1941. mAllSelfFields.add(field);
  1942. mSelfFields = null; // flush this, hopefully it hasn't been used yet.
  1943. }
  1944. /**
  1945. * Adds the enum constant.
  1946. *
  1947. * @param field the field
  1948. */
  1949. public void addEnumConstant(FieldInfo field) {
  1950. mApiCheckEnumConstants.put(field.name(), field);
  1951. mEnumConstants.add(field);
  1952. }
  1953. /**
  1954. * Sets the super class.
  1955. *
  1956. * @param superclass the new super class
  1957. */
  1958. public void setSuperClass(ClassInfo superclass) {
  1959. mRealSuperclass = superclass;
  1960. mSuperclass = superclass;
  1961. }
  1962. /**
  1963. * All constructors map.
  1964. *
  1965. * @return the map
  1966. */
  1967. public Map<String, MethodInfo> allConstructorsMap() {
  1968. return mApiCheckConstructors;
  1969. }
  1970. /**
  1971. * All fields.
  1972. *
  1973. * @return the map
  1974. */
  1975. public Map<String, FieldInfo> allFields() {
  1976. return mApiCheckFields;
  1977. }
  1978. /**
  1979. * Returns all methods defined directly in this class. For a list of all
  1980. * methods supported by this class, see {@link #methods()}.
  1981. *
  1982. * @return the map
  1983. */
  1984. public Map<String, MethodInfo> allMethods() {
  1985. return mApiCheckMethods;
  1986. }
  1987. /**
  1988. * Returns the class hierarchy for this class, starting with this class.
  1989. *
  1990. * @return the iterable
  1991. */
  1992. public Iterable<ClassInfo> hierarchy() {
  1993. List<ClassInfo> result = new ArrayList<ClassInfo>(4);
  1994. for (ClassInfo c = this; c != null; c = c.mSuperclass) {
  1995. result.add(c);
  1996. }
  1997. return result;
  1998. }
  1999. /**
  2000. * Superclass name.
  2001. *
  2002. * @return the string
  2003. */
  2004. public String superclassName() {
  2005. if (mSuperclass == null) {
  2006. if (mQualifiedName.equals("java.lang.Object")) {
  2007. return null;
  2008. }
  2009. throw new UnsupportedOperationException("Superclass not set for " + qualifiedName());
  2010. }
  2011. return mSuperclass.mQualifiedName;
  2012. }
  2013. /**
  2014. * Sets the annotations.
  2015. *
  2016. * @param annotations the new annotations
  2017. */
  2018. public void setAnnotations(ArrayList<AnnotationInstanceInfo> annotations) {
  2019. mAnnotations = annotations;
  2020. }
  2021. /**
  2022. * Checks if is consistent.
  2023. *
  2024. * @param cl the cl
  2025. * @return true, if is consistent
  2026. */
  2027. public boolean isConsistent(ClassInfo cl) {
  2028. boolean consistent = true;
  2029. if (isInterface() != cl.isInterface()) {
  2030. Errors.error(Errors.CHANGED_CLASS, cl.position(), "Class " + cl.qualifiedName()
  2031. + " changed class/interface declaration");
  2032. consistent = false;
  2033. }
  2034. for (ClassInfo iface : mRealInterfaces) {
  2035. if (!implementsInterface(cl, iface.mQualifiedName)) {
  2036. Errors.error(Errors.REMOVED_INTERFACE, cl.position(), "Class " + qualifiedName()
  2037. + " no longer implements " + iface);
  2038. }
  2039. }
  2040. for (ClassInfo iface : cl.mRealInterfaces) {
  2041. if (!implementsInterface(this, iface.mQualifiedName)) {
  2042. Errors.error(Errors.ADDED_INTERFACE, cl.position(), "Added interface " + iface
  2043. + " to class " + qualifiedName());
  2044. consistent = false;
  2045. }
  2046. }
  2047. for (MethodInfo mInfo : mApiCheckMethods.values()) {
  2048. if (cl.mApiCheckMethods.containsKey(mInfo.getHashableName())) {
  2049. if (!mInfo.isConsistent(cl.mApiCheckMethods.get(mInfo.getHashableName()))) {
  2050. consistent = false;
  2051. }
  2052. } else {
  2053. /*
  2054. * This class formerly provided this method directly, and now does not. Check our ancestry
  2055. * to see if there's an inherited version that still fulfills the API requirement.
  2056. */
  2057. MethodInfo mi = ClassInfo.overriddenMethod(mInfo, cl);
  2058. if (mi == null) {
  2059. mi = ClassInfo.interfaceMethod(mInfo, cl);
  2060. }
  2061. if (mi == null) {
  2062. Errors.error(Errors.REMOVED_METHOD, mInfo.position(), "Removed public method "
  2063. + mInfo.qualifiedName());
  2064. consistent = false;
  2065. }
  2066. }
  2067. }
  2068. for (MethodInfo mInfo : cl.mApiCheckMethods.values()) {
  2069. if (!mApiCheckMethods.containsKey(mInfo.getHashableName())) {
  2070. /*
  2071. * Similarly to the above, do not fail if this "new" method is really an override of an
  2072. * existing superclass method.
  2073. */
  2074. MethodInfo mi = ClassInfo.overriddenMethod(mInfo, this);
  2075. if (mi == null) {
  2076. Errors.error(Errors.ADDED_METHOD, mInfo.position(), "Added public method "
  2077. + mInfo.qualifiedName());
  2078. consistent = false;
  2079. }
  2080. }
  2081. }
  2082. for (MethodInfo mInfo : mApiCheckConstructors.values()) {
  2083. if (cl.mApiCheckConstructors.containsKey(mInfo.getHashableName())) {
  2084. if (!mInfo.isConsistent(cl.mApiCheckConstructors.get(mInfo.getHashableName()))) {
  2085. consistent = false;
  2086. }
  2087. } else {
  2088. Errors.error(Errors.REMOVED_METHOD, mInfo.position(), "Removed public constructor "
  2089. + mInfo.prettySignature());
  2090. consistent = false;
  2091. }
  2092. }
  2093. for (MethodInfo mInfo : cl.mApiCheckConstructors.values()) {
  2094. if (!mApiCheckConstructors.containsKey(mInfo.getHashableName())) {
  2095. Errors.error(Errors.ADDED_METHOD, mInfo.position(), "Added public constructor "
  2096. + mInfo.prettySignature());
  2097. consistent = false;
  2098. }
  2099. }
  2100. for (FieldInfo mInfo : mApiCheckFields.values()) {
  2101. if (cl.mApiCheckFields.containsKey(mInfo.name())) {
  2102. if (!mInfo.isConsistent(cl.mApiCheckFields.get(mInfo.name()))) {
  2103. consistent = false;
  2104. }
  2105. } else {
  2106. Errors.error(Errors.REMOVED_FIELD, mInfo.position(), "Removed field "
  2107. + mInfo.qualifiedName());
  2108. consistent = false;
  2109. }
  2110. }
  2111. for (FieldInfo mInfo : cl.mApiCheckFields.values()) {
  2112. if (!mApiCheckFields.containsKey(mInfo.name())) {
  2113. Errors.error(Errors.ADDED_FIELD, mInfo.position(), "Added public field "
  2114. + mInfo.qualifiedName());
  2115. consistent = false;
  2116. }
  2117. }
  2118. for (FieldInfo info : mApiCheckEnumConstants.values()) {
  2119. if (cl.mApiCheckEnumConstants.containsKey(info.name())) {
  2120. if (!info.isConsistent(cl.mApiCheckEnumConstants.get(info.name()))) {
  2121. consistent = false;
  2122. }
  2123. } else {
  2124. Errors.error(Errors.REMOVED_FIELD, info.position(), "Removed enum constant "
  2125. + info.qualifiedName());
  2126. consistent = false;
  2127. }
  2128. }
  2129. for (FieldInfo info : cl.mApiCheckEnumConstants.values()) {
  2130. if (!mApiCheckEnumConstants.containsKey(info.name())) {
  2131. Errors.error(Errors.ADDED_FIELD, info.position(), "Added enum constant "
  2132. + info.qualifiedName());
  2133. consistent = false;
  2134. }
  2135. }
  2136. if (mIsAbstract != cl.mIsAbstract) {
  2137. consistent = false;
  2138. Errors.error(Errors.CHANGED_ABSTRACT, cl.position(), "Class " + cl.qualifiedName()
  2139. + " changed abstract qualifier");
  2140. }
  2141. if (mIsFinal != cl.mIsFinal) {
  2142. consistent = false;
  2143. Errors.error(Errors.CHANGED_FINAL, cl.position(), "Class " + cl.qualifiedName()
  2144. + " changed final qualifier");
  2145. }
  2146. if (mIsStatic != cl.mIsStatic) {
  2147. consistent = false;
  2148. Errors.error(Errors.CHANGED_STATIC, cl.position(), "Class " + cl.qualifiedName()
  2149. + " changed static qualifier");
  2150. }
  2151. if (!scope().equals(cl.scope())) {
  2152. consistent = false;
  2153. Errors.error(Errors.CHANGED_SCOPE, cl.position(), "Class " + cl.qualifiedName()
  2154. + " scope changed from " + scope() + " to " + cl.scope());
  2155. }
  2156. if (!isDeprecated() == cl.isDeprecated()) {
  2157. consistent = false;
  2158. Errors.error(Errors.CHANGED_DEPRECATED, cl.position(), "Class " + cl.qualifiedName()
  2159. + " has changed deprecation state");
  2160. }
  2161. if (superclassName() != null) {
  2162. if (cl.superclassName() == null || !superclassName().equals(cl.superclassName())) {
  2163. consistent = false;
  2164. Errors.error(Errors.CHANGED_SUPERCLASS, cl.position(), "Class " + qualifiedName()
  2165. + " superclass changed from " + superclassName() + " to " + cl.superclassName());
  2166. }
  2167. } else if (cl.superclassName() != null) {
  2168. consistent = false;
  2169. Errors.error(Errors.CHANGED_SUPERCLASS, cl.position(), "Class " + qualifiedName()
  2170. + " superclass changed from " + "null to " + cl.superclassName());
  2171. }
  2172. return consistent;
  2173. }
  2174. // Find a superclass implementation of the given method.
  2175. /**
  2176. * Overridden method.
  2177. *
  2178. * @param candidate the candidate
  2179. * @param newClassObj the new class obj
  2180. * @return the method info
  2181. */
  2182. public static MethodInfo overriddenMethod(MethodInfo candidate, ClassInfo newClassObj) {
  2183. if (newClassObj == null) {
  2184. return null;
  2185. }
  2186. for (MethodInfo mi : newClassObj.mApiCheckMethods.values()) {
  2187. if (mi.matches(candidate)) {
  2188. // found it
  2189. return mi;
  2190. }
  2191. }
  2192. // not found here. recursively search ancestors
  2193. return ClassInfo.overriddenMethod(candidate, newClassObj.mSuperclass);
  2194. }
  2195. // Find a superinterface declaration of the given method.
  2196. /**
  2197. * Interface method.
  2198. *
  2199. * @param candidate the candidate
  2200. * @param newClassObj the new class obj
  2201. * @return the method info
  2202. */
  2203. public static MethodInfo interfaceMethod(MethodInfo candidate, ClassInfo newClassObj) {
  2204. if (newClassObj == null) {
  2205. return null;
  2206. }
  2207. for (ClassInfo interfaceInfo : newClassObj.interfaces()) {
  2208. for (MethodInfo mi : interfaceInfo.mApiCheckMethods.values()) {
  2209. if (mi.matches(candidate)) {
  2210. return mi;
  2211. }
  2212. }
  2213. }
  2214. return ClassInfo.interfaceMethod(candidate, newClassObj.mSuperclass);
  2215. }
  2216. /**
  2217. * Checks for constructor.
  2218. *
  2219. * @param constructor the constructor
  2220. * @return true, if successful
  2221. */
  2222. public boolean hasConstructor(MethodInfo constructor) {
  2223. String name = constructor.getHashableName();
  2224. for (MethodInfo ctor : mApiCheckConstructors.values()) {
  2225. if (name.equals(ctor.getHashableName())) {
  2226. return true;
  2227. }
  2228. }
  2229. return false;
  2230. }
  2231. /**
  2232. * Sets the type info.
  2233. *
  2234. * @param typeInfo the new type info
  2235. */
  2236. public void setTypeInfo(TypeInfo typeInfo) {
  2237. mTypeInfo = typeInfo;
  2238. }
  2239. /**
  2240. * Type.
  2241. *
  2242. * @return the type info
  2243. */
  2244. public TypeInfo type() {
  2245. return mTypeInfo;
  2246. }
  2247. /**
  2248. * Adds the inner class.
  2249. *
  2250. * @param innerClass the inner class
  2251. */
  2252. public void addInnerClass(ClassInfo innerClass) {
  2253. if (mInnerClasses == null) {
  2254. mInnerClasses = new ArrayList<ClassInfo>();
  2255. }
  2256. mInnerClasses.add(innerClass);
  2257. }
  2258. /**
  2259. * Sets the containing class.
  2260. *
  2261. * @param containingClass the new containing class
  2262. */
  2263. public void setContainingClass(ClassInfo containingClass) {
  2264. mContainingClass = containingClass;
  2265. }
  2266. /**
  2267. * Sets the superclass type.
  2268. *
  2269. * @param superclassType the new superclass type
  2270. */
  2271. public void setSuperclassType(TypeInfo superclassType) {
  2272. mRealSuperclassType = superclassType;
  2273. }
  2274. /**
  2275. * @see com.google.doclava.Resolvable#printResolutions()
  2276. */
  2277. public void printResolutions() {
  2278. if (mResolutions == null || mResolutions.isEmpty()) {
  2279. return;
  2280. }
  2281. System.out.println("Resolutions for Class " + mName + ":");
  2282. for (Resolution r : mResolutions) {
  2283. System.out.println(r);
  2284. }
  2285. }
  2286. /**
  2287. * @see com.google.doclava.Resolvable#addResolution(com.google.doclava.Resolution)
  2288. */
  2289. public void addResolution(Resolution resolution) {
  2290. if (mResolutions == null) {
  2291. mResolutions = new ArrayList<Resolution>();
  2292. }
  2293. mResolutions.add(resolution);
  2294. }
  2295. /**
  2296. * @see com.google.doclava.Resolvable#resolveResolutions()
  2297. */
  2298. public boolean resolveResolutions() {
  2299. ArrayList<Resolution> resolutions = mResolutions;
  2300. mResolutions = new ArrayList<Resolution>();
  2301. boolean allResolved = true;
  2302. for (Resolution resolution : resolutions) {
  2303. StringBuilder qualifiedClassName = new StringBuilder();
  2304. InfoBuilder.resolveQualifiedName(resolution.getValue(), qualifiedClassName,
  2305. resolution.getInfoBuilder());
  2306. // if we still couldn't resolve it, save it for the next pass
  2307. if ("".equals(qualifiedClassName.toString())) {
  2308. mResolutions.add(resolution);
  2309. allResolved = false;
  2310. } else if ("superclassQualifiedName".equals(resolution.getVariable())) {
  2311. setSuperClass(InfoBuilder.Caches.obtainClass(qualifiedClassName.toString()));
  2312. } else if ("interfaceQualifiedName".equals(resolution.getVariable())) {
  2313. addInterface(InfoBuilder.Caches.obtainClass(qualifiedClassName.toString()));
  2314. }
  2315. }
  2316. return allResolved;
  2317. }
  2318. }