1920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson/*
2920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Copyright (C) 2010 Google Inc.
3920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson *
4920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Licensed under the Apache License, Version 2.0 (the "License");
5920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * you may not use this file except in compliance with the License.
6920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * You may obtain a copy of the License at
7920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson *
8920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * http://www.apache.org/licenses/LICENSE-2.0
9920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson *
10920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Unless required by applicable law or agreed to in writing, software
11920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * distributed under the License is distributed on an "AS IS" BASIS,
12920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * See the License for the specific language governing permissions and
14920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * limitations under the License.
15920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */
16920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
17920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonpackage com.google.doclava;
18920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
19920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.google.clearsilver.jsilver.data.Data;
20920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.google.doclava.apicheck.AbstractMethodInfo;
21920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
22920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.*;
23920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
246ba612efffba42bec102ac58a1540496158f747eAndrew Sappersteinpublic class MethodInfo extends MemberInfo implements AbstractMethodInfo, Resolvable {
25920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static final Comparator<MethodInfo> comparator = new Comparator<MethodInfo>() {
26920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    public int compare(MethodInfo a, MethodInfo b) {
27d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        return a.name().compareTo(b.name());
28920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
29920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  };
30920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
31920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private class InlineTags implements InheritedTags {
32920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    public TagInfo[] tags() {
33920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return comment().tags();
34920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
35920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
36920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    public InheritedTags inherited() {
37920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      MethodInfo m = findOverriddenMethod(name(), signature());
38920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (m != null) {
39920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return m.inlineTags();
40920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
41920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return null;
42920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
43920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
44920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
45920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
46d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  private static void addInterfaces(ArrayList<ClassInfo> ifaces, ArrayList<ClassInfo> queue) {
47920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo i : ifaces) {
48920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      queue.add(i);
49920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
50920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo i : ifaces) {
51920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      addInterfaces(i.interfaces(), queue);
52920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
53920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
54920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
55920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  // first looks for a superclass, and then does a breadth first search to
56920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  // find the least far away match
57920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public MethodInfo findOverriddenMethod(String name, String signature) {
58920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mReturnType == null) {
59920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // ctor
60920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return null;
61920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
62920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mOverriddenMethod != null) {
63920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return mOverriddenMethod;
64920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
65920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
66920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
67920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    addInterfaces(containingClass().interfaces(), queue);
68920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo iface : queue) {
69920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (MethodInfo me : iface.methods()) {
70920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (me.name().equals(name) && me.signature().equals(signature)
71920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            && me.inlineTags().tags() != null && me.inlineTags().tags().length > 0) {
72920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return me;
73920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
74920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
75920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
76920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return null;
77920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
78920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
79d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  private static void addRealInterfaces(ArrayList<ClassInfo> ifaces, ArrayList<ClassInfo> queue) {
80920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo i : ifaces) {
81920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      queue.add(i);
82920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (i.realSuperclass() != null && i.realSuperclass().isAbstract()) {
83920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        queue.add(i.superclass());
84920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
85920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
86920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo i : ifaces) {
87920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      addInterfaces(i.realInterfaces(), queue);
88920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
89920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
90920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
91920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public MethodInfo findRealOverriddenMethod(String name, String signature, HashSet notStrippable) {
92920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mReturnType == null) {
93920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // ctor
94920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return null;
95920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
96920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mOverriddenMethod != null) {
97920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return mOverriddenMethod;
98920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
99920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
100920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
101920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (containingClass().realSuperclass() != null
102920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        && containingClass().realSuperclass().isAbstract()) {
103920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      queue.add(containingClass());
104920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
105920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    addInterfaces(containingClass().realInterfaces(), queue);
106920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo iface : queue) {
107920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (MethodInfo me : iface.methods()) {
108920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (me.name().equals(name) && me.signature().equals(signature)
109920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            && me.inlineTags().tags() != null && me.inlineTags().tags().length > 0
110920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            && notStrippable.contains(me.containingClass())) {
111920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return me;
112920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
113920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
114920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
115920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return null;
116920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
117920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
118920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public MethodInfo findSuperclassImplementation(HashSet notStrippable) {
119920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mReturnType == null) {
120920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // ctor
121920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return null;
122920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
123920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mOverriddenMethod != null) {
124920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Even if we're told outright that this was the overridden method, we want to
125920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // be conservative and ignore mismatches of parameter types -- they arise from
126920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // extending generic specializations, and we want to consider the derived-class
127920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // method to be a non-override.
128920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (this.signature().equals(mOverriddenMethod.signature())) {
129920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return mOverriddenMethod;
130920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
131920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
132920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
133920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
134920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (containingClass().realSuperclass() != null
135920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        && containingClass().realSuperclass().isAbstract()) {
136920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      queue.add(containingClass());
137920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
138920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    addInterfaces(containingClass().realInterfaces(), queue);
139920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo iface : queue) {
140920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (MethodInfo me : iface.methods()) {
141920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (me.name().equals(this.name()) && me.signature().equals(this.signature())
142920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            && notStrippable.contains(me.containingClass())) {
143920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return me;
144920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
145920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
146920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
147920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return null;
148920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
149920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
150920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public ClassInfo findRealOverriddenClass(String name, String signature) {
151920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mReturnType == null) {
152920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // ctor
153920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return null;
154920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
155920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mOverriddenMethod != null) {
156920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return mOverriddenMethod.mRealContainingClass;
157920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
158920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
159920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
160920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (containingClass().realSuperclass() != null
161920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        && containingClass().realSuperclass().isAbstract()) {
162920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      queue.add(containingClass());
163920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
164920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    addInterfaces(containingClass().realInterfaces(), queue);
165920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo iface : queue) {
166920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (MethodInfo me : iface.methods()) {
167920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (me.name().equals(name) && me.signature().equals(signature)
168920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            && me.inlineTags().tags() != null && me.inlineTags().tags().length > 0) {
169920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return iface;
170920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
171920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
172920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
173920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return null;
174920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
175920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
176920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private class FirstSentenceTags implements InheritedTags {
177920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    public TagInfo[] tags() {
178920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return comment().briefTags();
179920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
180920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
181920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    public InheritedTags inherited() {
182920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      MethodInfo m = findOverriddenMethod(name(), signature());
183920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (m != null) {
184920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return m.firstSentenceTags();
185920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
186920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return null;
187920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
188920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
189920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
190920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
191920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private class ReturnTags implements InheritedTags {
192920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    public TagInfo[] tags() {
193920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return comment().returnTags();
194920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
195920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
196920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    public InheritedTags inherited() {
197920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      MethodInfo m = findOverriddenMethod(name(), signature());
198920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (m != null) {
199920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return m.returnTags();
200920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
201920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return null;
202920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
203920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
204920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
205920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
206920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public boolean isDeprecated() {
207920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    boolean deprecated = false;
208920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (!mDeprecatedKnown) {
209920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      boolean commentDeprecated = comment().isDeprecated();
210920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      boolean annotationDeprecated = false;
211920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (AnnotationInstanceInfo annotation : annotations()) {
212920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (annotation.type().qualifiedName().equals("java.lang.Deprecated")) {
213920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          annotationDeprecated = true;
214920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          break;
215920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
216920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
217920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
218920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (commentDeprecated != annotationDeprecated) {
219920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        Errors.error(Errors.DEPRECATION_MISMATCH, position(), "Method "
220920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            + mContainingClass.qualifiedName() + "." + name()
221920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            + ": @Deprecated annotation and @deprecated doc tag do not match");
222920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
223920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
224920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mIsDeprecated = commentDeprecated | annotationDeprecated;
225920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mDeprecatedKnown = true;
226920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
227920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mIsDeprecated;
228920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
229920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
230920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public void setDeprecated(boolean deprecated) {
231920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mDeprecatedKnown = true;
232920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mIsDeprecated = deprecated;
233920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
234920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
235d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public ArrayList<TypeInfo> getTypeParameters() {
236920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mTypeParameters;
237920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
238920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
239920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public MethodInfo cloneForClass(ClassInfo newContainingClass) {
240920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    MethodInfo result =
241920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        new MethodInfo(getRawCommentText(), mTypeParameters, name(), signature(),
242920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            newContainingClass, realContainingClass(), isPublic(), isProtected(),
243920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            isPackagePrivate(), isPrivate(), isFinal(), isStatic(), isSynthetic(), mIsAbstract,
244920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            mIsSynchronized, mIsNative, mIsAnnotationElement, kind(), mFlatSignature,
245920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            mOverriddenMethod, mReturnType, mParameters, mThrownExceptions, position(),
246920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            annotations());
247920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    result.init(mDefaultAnnotationElementValue);
248920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return result;
249920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
250920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
251d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public MethodInfo(String rawCommentText, ArrayList<TypeInfo> typeParameters, String name,
252920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String signature, ClassInfo containingClass, ClassInfo realContainingClass, boolean isPublic,
253920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      boolean isProtected, boolean isPackagePrivate, boolean isPrivate, boolean isFinal,
254920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      boolean isStatic, boolean isSynthetic, boolean isAbstract, boolean isSynchronized,
255920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      boolean isNative, boolean isAnnotationElement, String kind, String flatSignature,
256d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      MethodInfo overriddenMethod, TypeInfo returnType, ArrayList<ParameterInfo> parameters,
257d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      ArrayList<ClassInfo> thrownExceptions, SourcePositionInfo position,
258d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      ArrayList<AnnotationInstanceInfo> annotations) {
259920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Explicitly coerce 'final' state of Java6-compiled enum values() method, to match
260920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // the Java5-emitted base API description.
261920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    super(rawCommentText, name, signature, containingClass, realContainingClass, isPublic,
262040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato        isProtected, isPackagePrivate, isPrivate,
263040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato        ((name.equals("values") && containingClass.isEnum()) ? true : isFinal),
264040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato        isStatic, isSynthetic, kind, position, annotations);
265920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
266920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // The underlying MethodDoc for an interface's declared methods winds up being marked
267920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // non-abstract. Correct that here by looking at the immediate-parent class, and marking
268920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // this method abstract if it is an unimplemented interface method.
269920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (containingClass.isInterface()) {
270920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      isAbstract = true;
271920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
272920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
273920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mReasonOpened = "0:0";
274920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mIsAnnotationElement = isAnnotationElement;
275920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mTypeParameters = typeParameters;
276920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mIsAbstract = isAbstract;
277920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mIsSynchronized = isSynchronized;
278920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mIsNative = isNative;
279920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mFlatSignature = flatSignature;
280920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mOverriddenMethod = overriddenMethod;
281920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mReturnType = returnType;
282920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mParameters = parameters;
283920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mThrownExceptions = thrownExceptions;
284920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
285920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
286920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public void init(AnnotationValueInfo defaultAnnotationElementValue) {
287920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mDefaultAnnotationElementValue = defaultAnnotationElementValue;
288920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
289920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
290920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public boolean isAbstract() {
291920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mIsAbstract;
292920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
293920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
294920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public boolean isSynchronized() {
295920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mIsSynchronized;
296920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
297920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
298920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public boolean isNative() {
299920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mIsNative;
300920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
301920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
302920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String flatSignature() {
303920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mFlatSignature;
304920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
305920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
306920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public InheritedTags inlineTags() {
307920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return new InlineTags();
308920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
309920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
310920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public InheritedTags firstSentenceTags() {
311920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return new FirstSentenceTags();
312920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
313920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
314920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public InheritedTags returnTags() {
315920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return new ReturnTags();
316920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
317920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
318920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public TypeInfo returnType() {
319920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mReturnType;
320920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
321920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
322920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String prettySignature() {
323920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return name() + prettyParameters();
324920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
325920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
326920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
327920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Returns a printable version of the parameters of this method's signature.
328920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
329920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String prettyParameters() {
330920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    StringBuilder params = new StringBuilder("(");
331920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ParameterInfo pInfo : mParameters) {
332920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (params.length() > 1) {
333920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        params.append(",");
334920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
335920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      params.append(pInfo.type().simpleTypeName());
336920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
337920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
338920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    params.append(")");
339920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return params.toString();
340920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
341920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
342920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
343920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Returns a name consistent with the {@link com.google.doclava.MethodInfo#getHashableName()}.
344920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
345920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String getHashableName() {
346920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    StringBuilder result = new StringBuilder();
347920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    result.append(name());
348d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
349d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    if (mParameters == null) {
350d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        return result.toString();
351d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    }
352d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
353d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    int i = 0;
354d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    for (ParameterInfo param : mParameters) {
355920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      result.append(":");
356d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      if (i == (mParameters.size()-1) && isVarArgs()) {
357920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // TODO: note that this does not attempt to handle hypothetical
358920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // vararg methods whose last parameter is a list of arrays, e.g.
359920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // "Object[]...".
360d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        result.append(param.type().fullNameNoDimension(typeVariables())).append("...");
361920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
362d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        result.append(param.type().fullName(typeVariables()));
363920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
364d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      i++;
365920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
366920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return result.toString();
367920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
368920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
369920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private boolean inList(ClassInfo item, ThrowsTagInfo[] list) {
370920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int len = list.length;
371920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String qn = item.qualifiedName();
372920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < len; i++) {
373920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo ex = list[i].exception();
374920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (ex != null && ex.qualifiedName().equals(qn)) {
375920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return true;
376920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
377920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
378920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return false;
379920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
380920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
381920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public ThrowsTagInfo[] throwsTags() {
382920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mThrowsTags == null) {
383920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ThrowsTagInfo[] documented = comment().throwsTags();
384920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ArrayList<ThrowsTagInfo> rv = new ArrayList<ThrowsTagInfo>();
385920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
386920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      int len = documented.length;
387920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (int i = 0; i < len; i++) {
388920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        rv.add(documented[i]);
389920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
390920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
391d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      for (ClassInfo cl : mThrownExceptions) {
392920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (documented == null || !inList(cl, documented)) {
393920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          rv.add(new ThrowsTagInfo("@throws", "@throws", cl.qualifiedName(), cl, "",
394920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              containingClass(), position()));
395920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
396920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
397920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mThrowsTags = rv.toArray(new ThrowsTagInfo[rv.size()]);
398920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
399920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mThrowsTags;
400920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
401920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
402920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static int indexOfParam(String name, String[] list) {
403920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    final int N = list.length;
404920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < N; i++) {
405920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (name.equals(list[i])) {
406920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return i;
407920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
408920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
409920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return -1;
410920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
411920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
412920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public ParamTagInfo[] paramTags() {
413920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mParamTags == null) {
414d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      final int N = mParameters.size();
415920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
416920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String[] names = new String[N];
417920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String[] comments = new String[N];
418920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      SourcePositionInfo[] positions = new SourcePositionInfo[N];
419920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
420920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // get the right names so we can handle our names being different from
421920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // our parent's names.
422d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      int i = 0;
423d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      for (ParameterInfo param : mParameters) {
424d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        names[i] = param.name();
425920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        comments[i] = "";
426d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        positions[i] = param.position();
427d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        i++;
428920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
429920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
430920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // gather our comments, and complain about misnamed @param tags
431920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (ParamTagInfo tag : comment().paramTags()) {
432920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        int index = indexOfParam(tag.parameterName(), names);
433920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (index >= 0) {
434920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          comments[index] = tag.parameterComment();
435920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          positions[index] = tag.position();
436920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        } else {
437920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          Errors.error(Errors.UNKNOWN_PARAM_TAG_NAME, tag.position(),
438920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              "@param tag with name that doesn't match the parameter list: '" + tag.parameterName()
439920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                  + "'");
440920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
441920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
442920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
443920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // get our parent's tags to fill in the blanks
444920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      MethodInfo overridden = this.findOverriddenMethod(name(), signature());
445920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (overridden != null) {
446920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        ParamTagInfo[] maternal = overridden.paramTags();
447d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        for (i = 0; i < N; i++) {
448920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          if (comments[i].equals("")) {
449920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            comments[i] = maternal[i].parameterComment();
450920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            positions[i] = maternal[i].position();
451920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
452920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
453920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
454920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
455920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // construct the results, and cache them for next time
456920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mParamTags = new ParamTagInfo[N];
457d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      for (i = 0; i < N; i++) {
458920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        mParamTags[i] =
459920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            new ParamTagInfo("@param", "@param", names[i] + " " + comments[i], parent(),
460920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                positions[i]);
461920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
462920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // while we're here, if we find any parameters that are still undocumented at this
463920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // point, complain. (this warning is off by default, because it's really, really
464920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // common; but, it's good to be able to enforce it)
465920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (comments[i].equals("")) {
466920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          Errors.error(Errors.UNDOCUMENTED_PARAMETER, positions[i], "Undocumented parameter '"
467920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              + names[i] + "' on method '" + name() + "'");
468920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
469920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
470920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
471920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mParamTags;
472920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
473920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
474920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public SeeTagInfo[] seeTags() {
475920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    SeeTagInfo[] result = comment().seeTags();
476920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (result == null) {
477920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (mOverriddenMethod != null) {
478920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        result = mOverriddenMethod.seeTags();
479920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
480920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
481920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return result;
482920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
483920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
484920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public TagInfo[] deprecatedTags() {
485920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TagInfo[] result = comment().deprecatedTags();
486920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (result.length == 0) {
487920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (comment().undeprecateTags().length == 0) {
488920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (mOverriddenMethod != null) {
489920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          result = mOverriddenMethod.deprecatedTags();
490920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
491920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
492920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
493920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return result;
494920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
495920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
496d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public ArrayList<ParameterInfo> parameters() {
497920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mParameters;
498920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
499920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
500920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
501920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public boolean matchesParams(String[] params, String[] dimensions, boolean varargs) {
502920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mParamStrings == null) {
503d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      if (mParameters.size() != params.length) {
504920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return false;
505920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
506d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      int i = 0;
507d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      for (ParameterInfo mine : mParameters) {
508d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        if (!mine.matchesDimension(dimensions[i], varargs)) {
509920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return false;
510920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
511d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        TypeInfo myType = mine.type();
512920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        String qualifiedName = myType.qualifiedTypeName();
513920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        String realType = myType.isPrimitive() ? "" : myType.asClassInfo().qualifiedName();
514920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        String s = params[i];
515920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        int slen = s.length();
516920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        int qnlen = qualifiedName.length();
517920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
518920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // Check for a matching generic name or best known type
519920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (!matchesType(qualifiedName, s) && !matchesType(realType, s)) {
520920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return false;
521920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
522d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        i++;
523920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
524920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
525920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return true;
526920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
527920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
528920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
529920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Checks to see if a parameter from a method signature is
530920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * compatible with a parameter given in a {@code @link} tag.
531920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
532920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private boolean matchesType(String signatureParam, String callerParam) {
533920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int signatureLength = signatureParam.length();
534920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int callerLength = callerParam.length();
535920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return ((signatureParam.equals(callerParam) || ((callerLength + 1) < signatureLength
536920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        && signatureParam.charAt(signatureLength - callerLength - 1) == '.'
537920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        && signatureParam.endsWith(callerParam))));
538920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
539920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
540920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public void makeHDF(Data data, String base) {
541920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue(base + ".kind", kind());
542920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue(base + ".name", name());
543920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue(base + ".href", htmlPage());
544920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue(base + ".anchor", anchor());
545920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
546920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mReturnType != null) {
547920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      returnType().makeHDF(data, base + ".returnType", false, typeVariables());
548920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue(base + ".abstract", mIsAbstract ? "abstract" : "");
549920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
550920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
551920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue(base + ".synchronized", mIsSynchronized ? "synchronized" : "");
552920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue(base + ".final", isFinal() ? "final" : "");
553920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue(base + ".static", isStatic() ? "static" : "");
554920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
555920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TagInfo.makeHDF(data, base + ".shortDescr", firstSentenceTags());
556920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TagInfo.makeHDF(data, base + ".descr", inlineTags());
557920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TagInfo.makeHDF(data, base + ".deprecated", deprecatedTags());
558920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TagInfo.makeHDF(data, base + ".seeAlso", seeTags());
559920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue(base + ".since", getSince());
56040ad14799644f497483efe6d1350c856d46bc4daScott Main    if (isDeprecated()) {
56140ad14799644f497483efe6d1350c856d46bc4daScott Main      data.setValue(base + ".deprecatedsince", getDeprecatedSince());
56240ad14799644f497483efe6d1350c856d46bc4daScott Main    }
563920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ParamTagInfo.makeHDF(data, base + ".paramTags", paramTags());
564920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    AttrTagInfo.makeReferenceHDF(data, base + ".attrRefs", comment().attrTags());
565920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ThrowsTagInfo.makeHDF(data, base + ".throws", throwsTags());
566d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    ParameterInfo.makeHDF(data, base + ".params", mParameters.toArray(new ParameterInfo[mParameters.size()]), isVarArgs(), typeVariables());
567920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (isProtected()) {
568920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue(base + ".scope", "protected");
569920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else if (isPublic()) {
570920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue(base + ".scope", "public");
571920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
572920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TagInfo.makeHDF(data, base + ".returns", returnTags());
573920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
574920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mTypeParameters != null) {
575920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      TypeInfo.makeHDF(data, base + ".generic.typeArguments", mTypeParameters, false);
576920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
577920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
578920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    setFederatedReferences(data, base);
579920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
580920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
581920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public HashSet<String> typeVariables() {
582920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    HashSet<String> result = TypeInfo.typeVariables(mTypeParameters);
583920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo cl = containingClass();
584920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    while (cl != null) {
585d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        ArrayList<TypeInfo> types = cl.asTypeInfo().typeArguments();
586920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (types != null) {
587920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        TypeInfo.typeVariables(types, result);
588920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
589920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      cl = cl.containingClass();
590920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
591920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return result;
592920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
593920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
594920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  @Override
595920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public boolean isExecutable() {
596920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return true;
597920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
598920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
599d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public ArrayList<ClassInfo> thrownExceptions() {
600920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mThrownExceptions;
601920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
602920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
603920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String typeArgumentsName(HashSet<String> typeVars) {
604d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    if (mTypeParameters == null || mTypeParameters.isEmpty()) {
605920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return "";
606920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else {
607920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return TypeInfo.typeArgumentsName(mTypeParameters, typeVars);
608920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
609920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
610920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
611920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public boolean isAnnotationElement() {
612920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mIsAnnotationElement;
613920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
614920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
615920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public AnnotationValueInfo defaultAnnotationElementValue() {
616920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mDefaultAnnotationElementValue;
617920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
618920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
619920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public void setVarargs(boolean set) {
620920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mIsVarargs = set;
621920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
622920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
623920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public boolean isVarArgs() {
624920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mIsVarargs;
625920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
626920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
627920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  @Override
628920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String toString() {
629920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return this.name();
630920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
631920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
632920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public void setReason(String reason) {
633920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mReasonOpened = reason;
634920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
635920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
636920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String getReason() {
637920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mReasonOpened;
638920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
639920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
640920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public void addException(String exec) {
641920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo exceptionClass = new ClassInfo(exec);
642d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
643d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    mThrownExceptions.add(exceptionClass);
644920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
645920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
646920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public void addParameter(ParameterInfo p) {
647920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Name information
648920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mParameters == null) {
649d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        mParameters = new ArrayList<ParameterInfo>();
650920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
651d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
652d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    mParameters.add(p);
653920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
654920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
655920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private String mFlatSignature;
656920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private MethodInfo mOverriddenMethod;
657920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private TypeInfo mReturnType;
658920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private boolean mIsAnnotationElement;
659920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private boolean mIsAbstract;
660920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private boolean mIsSynchronized;
661920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private boolean mIsNative;
662920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private boolean mIsVarargs;
663920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private boolean mDeprecatedKnown;
664920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private boolean mIsDeprecated;
665d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  private ArrayList<ParameterInfo> mParameters;
666d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  private ArrayList<ClassInfo> mThrownExceptions;
667920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private String[] mParamStrings;
668d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  private ThrowsTagInfo[] mThrowsTags;
669920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private ParamTagInfo[] mParamTags;
670d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  private ArrayList<TypeInfo> mTypeParameters;
671920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private AnnotationValueInfo mDefaultAnnotationElementValue;
672920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private String mReasonOpened;
6736ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein  private ArrayList<Resolution> mResolutions;
674920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
675920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  // TODO: merge with droiddoc version (above)
676920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String qualifiedName() {
677920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String parentQName = (containingClass() != null)
678920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        ? (containingClass().qualifiedName() + ".") : "";
679920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return parentQName + name();
680920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
681920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
682920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  @Override
683920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String signature() {
684920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mSignature == null) {
685920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      StringBuilder params = new StringBuilder("(");
686920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (ParameterInfo pInfo : mParameters) {
687920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (params.length() > 1) {
688920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          params.append(", ");
689920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
690920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        params.append(pInfo.type().fullName());
691920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
692920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
693920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      params.append(")");
694920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mSignature = params.toString();
695920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
696920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mSignature;
697920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
698920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
699920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public boolean matches(MethodInfo other) {
700beef1457a4e56e88001bc68bd0d4742baf2adf18Ben Dodson    return prettySignature().equals(other.prettySignature());
701920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
702920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
703920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public boolean throwsException(ClassInfo exception) {
704920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo e : mThrownExceptions) {
705920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (e.qualifiedName().equals(exception.qualifiedName())) {
706920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return true;
707920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
708920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
709920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return false;
710920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
711920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
712920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public boolean isConsistent(MethodInfo mInfo) {
713920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    boolean consistent = true;
714040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato    if (this.mReturnType != mInfo.mReturnType && !this.mReturnType.equals(mInfo.mReturnType)) {
715920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      consistent = false;
716920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Errors.error(Errors.CHANGED_TYPE, mInfo.position(), "Method " + mInfo.qualifiedName()
717920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          + " has changed return type from " + mReturnType + " to " + mInfo.mReturnType);
718920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
719920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
720920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mIsAbstract != mInfo.mIsAbstract) {
721920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      consistent = false;
722920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Errors.error(Errors.CHANGED_ABSTRACT, mInfo.position(), "Method " + mInfo.qualifiedName()
723920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          + " has changed 'abstract' qualifier");
724920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
725920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
726920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mIsNative != mInfo.mIsNative) {
727920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      consistent = false;
728920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Errors.error(Errors.CHANGED_NATIVE, mInfo.position(), "Method " + mInfo.qualifiedName()
729920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          + " has changed 'native' qualifier");
730920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
731920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
732920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mIsFinal != mInfo.mIsFinal) {
733920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Compiler-generated methods vary in their 'final' qual between versions of
734920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // the compiler, so this check needs to be quite narrow. A change in 'final'
735920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // status of a method is only relevant if (a) the method is not declared 'static'
736920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // and (b) the method's class is not itself 'final'.
737920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (!mIsStatic) {
738920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if ((containingClass() == null) || (!containingClass().isFinal())) {
739920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          consistent = false;
740920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          Errors.error(Errors.CHANGED_FINAL, mInfo.position(), "Method " + mInfo.qualifiedName()
741920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              + " has changed 'final' qualifier");
742920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
743920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
744920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
745920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
746920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mIsStatic != mInfo.mIsStatic) {
747920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      consistent = false;
748920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Errors.error(Errors.CHANGED_STATIC, mInfo.position(), "Method " + mInfo.qualifiedName()
749920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          + " has changed 'static' qualifier");
750920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
751920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
752920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (!scope().equals(mInfo.scope())) {
753920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      consistent = false;
754920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Errors.error(Errors.CHANGED_SCOPE, mInfo.position(), "Method " + mInfo.qualifiedName()
755920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          + " changed scope from " + scope() + " to " + mInfo.scope());
756920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
757920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
758920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (!isDeprecated() == mInfo.isDeprecated()) {
759920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Errors.error(Errors.CHANGED_DEPRECATED, mInfo.position(), "Method " + mInfo.qualifiedName()
760040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato          + " has changed deprecation state " + isDeprecated() + " --> " + mInfo.isDeprecated());
761920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      consistent = false;
762920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
763920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
764cd020c30a870477480261fbb1463afae4cddd42eGlenn Kasten    // see JLS 3 13.4.20 "Adding or deleting a synchronized modifier of a method does not break "
765cd020c30a870477480261fbb1463afae4cddd42eGlenn Kasten    // "compatibility with existing binaries."
766cd020c30a870477480261fbb1463afae4cddd42eGlenn Kasten    /*
767920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mIsSynchronized != mInfo.mIsSynchronized) {
768920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Errors.error(Errors.CHANGED_SYNCHRONIZED, mInfo.position(), "Method " + mInfo.qualifiedName()
769920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          + " has changed 'synchronized' qualifier from " + mIsSynchronized + " to "
770920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          + mInfo.mIsSynchronized);
771920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      consistent = false;
772920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
773cd020c30a870477480261fbb1463afae4cddd42eGlenn Kasten    */
774920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
775920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo exception : thrownExceptions()) {
776920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (!mInfo.throwsException(exception)) {
777920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // exclude 'throws' changes to finalize() overrides with no arguments
778d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        if (!name().equals("finalize") || (!mParameters.isEmpty())) {
779920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          Errors.error(Errors.CHANGED_THROWS, mInfo.position(), "Method " + mInfo.qualifiedName()
780920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              + " no longer throws exception " + exception.qualifiedName());
781920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          consistent = false;
782920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
783920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
784920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
785920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
786920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo exec : mInfo.thrownExceptions()) {
787920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // exclude 'throws' changes to finalize() overrides with no arguments
788920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (!throwsException(exec)) {
789d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        if (!name().equals("finalize") || (!mParameters.isEmpty())) {
790920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          Errors.error(Errors.CHANGED_THROWS, mInfo.position(), "Method " + mInfo.qualifiedName()
791920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              + " added thrown exception " + exec.qualifiedName());
792920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          consistent = false;
793920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
794920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
795920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
796920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
797920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return consistent;
798920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
799d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
800d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public void printResolutions() {
8016ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      if (mResolutions == null || mResolutions.isEmpty()) {
8026ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein          return;
8036ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      }
8046ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
805d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      System.out.println("Resolutions for Method " + mName + mFlatSignature + ":");
806d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
8076ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      for (Resolution r : mResolutions) {
8086ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein          System.out.println(r);
8096ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      }
8106ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein  }
8116ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
8126ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein  public void addResolution(Resolution resolution) {
8136ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      if (mResolutions == null) {
8146ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein          mResolutions = new ArrayList<Resolution>();
8156ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      }
8166ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
8176ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      mResolutions.add(resolution);
8186ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein  }
8196ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
8206ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein  public boolean resolveResolutions() {
8216ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      ArrayList<Resolution> resolutions = mResolutions;
8226ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      mResolutions = new ArrayList<Resolution>();
8236ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
8246ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      boolean allResolved = true;
8256ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      for (Resolution resolution : resolutions) {
8266ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein          StringBuilder qualifiedClassName = new StringBuilder();
8276ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein          InfoBuilder.resolveQualifiedName(resolution.getValue(), qualifiedClassName,
8286ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein                  resolution.getInfoBuilder());
8296ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
8306ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein          // if we still couldn't resolve it, save it for the next pass
8316ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein          if ("".equals(qualifiedClassName.toString())) {
8326ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein              mResolutions.add(resolution);
8336ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein              allResolved = false;
8346ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein          } else if ("thrownException".equals(resolution.getVariable())) {
8356ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein              mThrownExceptions.add(InfoBuilder.Caches.obtainClass(qualifiedClassName.toString()));
8366ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein          }
8376ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      }
8386ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
8396ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      return allResolved;
840d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  }
841920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
842