Import GNU Classpath (20121202).
[official-gcc.git] / libjava / classpath / tools / gnu / classpath / tools / gjdoc / ExecutableMemberDocImpl.java
blob8f2a49c99c5c1a81073ea63f162739a21c92e9c1
1 /* gnu.classpath.tools.gjdoc.ExecutableMemberDocImpl
2 Copyright (C) 2001, 2012 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package gnu.classpath.tools.gjdoc;
40 import java.util.*;
41 import java.io.*;
42 import com.sun.javadoc.*;
44 public class ExecutableMemberDocImpl extends MemberDocImpl implements ExecutableMemberDoc {
46 protected ExecutableMemberDocImpl(ClassDoc containingClass,
47 PackageDoc containingPackage,
48 SourcePosition position) {
50 super(containingClass,
51 containingPackage,
52 position);
55 protected boolean processModifier(String word) {
56 if (super.processModifier(word)) {
57 return true;
59 else if (word.equals("synchronized")) {
60 isSynchronized=true;
61 return true;
63 else if (word.equals("native")) {
64 isNative=true;
65 return true;
67 else if (word.equals("abstract")) {
68 isAbstract=true;
69 return true;
71 else {
72 return false;
76 private boolean isAbstract=false;
77 private boolean isNative=false;
78 private boolean isSynchronized=false;
80 public boolean isAbstract() { return isAbstract; }
82 public boolean isNative() { return isNative; }
84 public boolean isSynchronized() { return isSynchronized; }
86 public ClassDoc[] thrownExceptions() { return thrownExceptions; }
88 public Parameter[] parameters() { return parameters; }
90 public ThrowsTag[] throwsTags() {
91 return (ThrowsTag[])getTagArr("throws", throwsTagEmptyArr);
94 public ParamTag[] paramTags() {
95 return (ParamTag[])getTagArr("param", paramTagEmptyArr);
98 public String signature() { return signature; }
99 public String flatSignature() { return flatSignature; }
101 public ClassDoc overriddenClass() {
102 for (ClassDoc cdi=(ClassDoc)containingClass().superclass(); cdi!=null; cdi=(ClassDoc)cdi.superclass()) {
103 if (null!=ClassDocImpl.findMethod(cdi, name(), signature()))
104 return cdi;
106 return null;
109 public static ExecutableMemberDocImpl createFromSource(ClassDoc containingClass,
110 PackageDoc containingPackage,
111 char[] source, int startIndex, int endIndex) throws IOException, ParseException {
113 int lastchar=32;
114 StringBuffer methodName=new StringBuffer();
115 for (int i=startIndex; i<endIndex && source[i]!='('; ++i) {
116 if ((Parser.WHITESPACE.indexOf(lastchar)>=0 && Parser.WHITESPACE.indexOf(source[i])<0)
117 || (lastchar == ']' && Parser.WHITESPACE.indexOf(source[i])<0 && '[' != source[i])) {
118 methodName.setLength(0);
119 methodName.append(source[i]);
121 else if (Parser.WHITESPACE.indexOf(source[i])<0) {
122 methodName.append(source[i]);
124 lastchar=source[i];
127 ExecutableMemberDocImpl rc;
129 SourcePosition position = DocImpl.getPosition(containingClass, source, startIndex);
131 if (methodName.toString().equals(((ClassDocImpl)containingClass).getClassName())) {
133 // Constructor
135 rc=new ConstructorDocImpl(containingClass,
136 containingPackage,
137 position);
139 else {
141 // Normal method
143 rc=new MethodDocImpl(containingClass,
144 containingPackage,
145 position);
148 if (containingClass.isInterface())
149 rc.accessLevel=ACCESS_PUBLIC;
151 int ndx=rc.parseModifiers(source, startIndex, endIndex);
152 StringBuffer name = new StringBuffer();
154 final int STATE_NORMAL=1;
155 final int STATE_STARC=2;
156 final int STATE_SLASHC=3;
158 int state=STATE_NORMAL;
160 while (source[ndx]!='(' && ndx<endIndex) {
161 if (state==STATE_NORMAL) {
162 if (ndx<endIndex-1 && source[ndx]=='/' && source[ndx+1]=='/') {
163 ++ndx;
164 state=STATE_SLASHC;
166 else if (ndx<endIndex-1 && source[ndx]=='/' && source[ndx+1]=='*') {
167 ++ndx;
168 state=STATE_STARC;
170 else {
171 name.append(source[ndx]);
174 else if (state==STATE_SLASHC) {
175 if (source[ndx]=='\n')
176 state=STATE_NORMAL;
178 else if (state==STATE_STARC) {
179 if (ndx<endIndex-1 && source[ndx]=='*' && source[ndx+1]=='/') {
180 ++ndx;
181 state=STATE_NORMAL;
184 ++ndx;
186 rc.setName(name.toString().trim());
188 state=STATE_NORMAL;
190 ++ndx;
191 int endx;
192 String param="";
193 List parameterList=new ArrayList();
194 for (endx=ndx; endx<endIndex; ++endx) {
195 if (state==STATE_SLASHC) {
196 if (source[endx]=='\n') {
197 state=STATE_NORMAL;
200 else if (state==STATE_STARC) {
201 if (source[endx]=='*' && source[endx+1]=='/') {
202 state=STATE_NORMAL;
203 ++endx;
206 else if (source[endx]=='/' && source[endx+1]=='*') {
207 state=STATE_STARC;
208 ++endx;
210 else if (source[endx]=='/' && source[endx+1]=='/') {
211 state=STATE_SLASHC;
212 ++endx;
214 else if (source[endx]==',' || source[endx]==')') {
215 param=param.trim();
216 if (param.length()>0) {
217 int n = param.length()-1;
218 int paramNameStart = 0;
219 while (n >= 0) {
220 char c = param.charAt(n);
221 if ('[' == c || ']' == c || Parser.WHITESPACE.indexOf(c)>=0) {
222 paramNameStart = n + 1;
223 break;
225 else {
226 -- n;
229 while (n >= 0 && ('[' == param.charAt(n)
230 || ']' == param.charAt(n)
231 || Parser.WHITESPACE.indexOf(param.charAt(n))>=0)) {
232 -- n;
234 int paramTypeEnd = n + 1;
235 int paramTypeStart = 0;
236 while (n >= 0) {
237 char c = param.charAt(n);
238 if ('[' == c || ']' == c || Parser.WHITESPACE.indexOf(c)>=0) {
239 paramTypeStart = n + 1;
240 break;
242 else {
243 -- n;
247 String paramType;
248 String paramName;
249 if (0 != paramNameStart) {
250 paramType=param.substring(paramTypeStart, paramTypeEnd);
251 paramName=param.substring(paramNameStart);
253 else {
254 paramName = "";
255 StringBuffer paramTypeBuffer = new StringBuffer();
256 for (int i=0; i<param.length(); ++i) {
257 char c = param.charAt(i);
258 if ('[' != c && ']' != c && Parser.WHITESPACE.indexOf(c)<0) {
259 paramTypeBuffer.append(c);
262 paramType = paramTypeBuffer.toString();
264 String dimSuffix="";
266 for (int i=0; i<param.length(); ++i) {
267 if ('[' == param.charAt(i)) {
268 dimSuffix += "[]";
271 paramType+=dimSuffix;
273 if (paramType.startsWith("[")) {
274 System.err.println("broken param type in " + rc + " in " +containingClass);
277 parameterList.add(new ParameterImpl(paramName, paramType,
278 ((ClassDocImpl)containingClass).typeForString(paramType)));
280 param="";
283 else
284 param+=source[endx];
286 if (source[endx]==')' && state==STATE_NORMAL)
287 break;
290 rc.setParameters((Parameter[])parameterList.toArray(new Parameter[0]));
292 ++endx;
293 String word="";
294 String dimSuffix="";
295 boolean haveThrowsKeyword=false;
296 List thrownExceptionsList=new ArrayList();
298 state=STATE_NORMAL;
299 for (; endx<endIndex; ++endx) {
300 if (state==STATE_SLASHC) {
301 if (source[endx]=='\n') state=STATE_NORMAL;
303 else if (state==STATE_STARC) {
304 if (source[endx]=='*' && source[endx+1]=='/') {
305 state=STATE_NORMAL;
306 ++endx;
309 else if (source[endx]=='/' && source[endx+1]=='*') {
310 state=STATE_STARC;
311 ++endx;
313 else if (source[endx]=='/' && source[endx+1]=='/') {
314 state=STATE_SLASHC;
315 ++endx;
317 else if (Parser.WHITESPACE.indexOf(source[endx])>=0) {
318 word=word.trim();
319 if (!haveThrowsKeyword && word.length()>0) {
320 if (word.equals("throws")) haveThrowsKeyword=true;
321 else System.err.println("ARGH! "+word);
322 word="";
325 else if (source[endx]=='[' || source[endx]==']') {
326 dimSuffix += source[endx];
328 else if (source[endx]==',' || source[endx]=='{' || source[endx]==';') {
329 word=word.trim();
330 if (word.length()>0) {
331 ClassDoc exceptionType=rc.containingClass().findClass(word);
332 if (exceptionType==null) {
333 exceptionType=new ClassDocProxy(word,
334 rc.containingClass());
336 thrownExceptionsList.add(exceptionType);
338 if (source[endx]=='{') {
339 break;
341 else {
342 word="";
345 else {
346 word+=source[endx];
350 if (dimSuffix.length()>0) {
351 rc.setTypeName(rc.getTypeName()+dimSuffix);
354 rc.setThrownExceptions((ClassDoc[])thrownExceptionsList.toArray(new ClassDoc[0]));
356 return rc;
359 private ClassDoc[] thrownExceptions;
360 private Parameter[] parameters;
361 private String signature;
362 private String flatSignature;
364 void setParameters(Parameter[] parameters) {
365 this.parameters=parameters;
368 void setThrownExceptions(ClassDoc[] thrownExceptions) {
369 this.thrownExceptions=thrownExceptions;
372 void resolve() {
374 for (int i=0; i<thrownExceptions.length; ++i) {
375 if (thrownExceptions[i] instanceof ClassDocProxy) {
376 String className=thrownExceptions[i].qualifiedName();
377 ClassDoc realClassDoc=containingClass().findClass(className);
378 if (realClassDoc!=null)
379 thrownExceptions[i]=realClassDoc;
383 StringBuffer signatureBuf=new StringBuffer();
384 StringBuffer flatSignatureBuf=new StringBuffer();
386 for (int i=0; i<parameters.length; ++i) {
387 ((ParameterImpl)parameters[i]).resolve(containingClass());
389 if (signatureBuf.length()>0) {
390 signatureBuf.append(",");
391 flatSignatureBuf.append(",");
393 signatureBuf.append(parameters[i].type().qualifiedTypeName());
394 flatSignatureBuf.append(parameters[i].type().typeName());
395 signatureBuf.append(parameters[i].type().dimension());
396 flatSignatureBuf.append(parameters[i].type().dimension());
398 this.signature="("+signatureBuf.toString()+")";
399 this.flatSignature="("+flatSignatureBuf.toString()+")";
401 super.resolve();
405 public int compareTo(Doc d) {
406 int rc;
407 if (d instanceof MemberDocImpl) {
408 MemberDocImpl otherMember = (MemberDocImpl)d;
409 rc = name().compareTo(otherMember.name());
410 if (0 == rc) {
411 if (d instanceof ExecutableMemberDocImpl) {
412 rc = signature().compareTo(((ExecutableMemberDocImpl)d).signature());
413 if (0 == rc) {
414 return containingClass().compareTo(otherMember.containingClass());
417 else {
418 rc = 1;
422 else {
423 rc = 1;
425 return rc;