KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > tools > ajdoc > SeeTagImpl


1 /* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the debugger and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  */

22 package org.aspectj.tools.ajdoc;
23
24 import org.aspectj.ajdoc.AdviceDoc;
25 import org.aspectj.ajdoc.AspectDoc;
26 import org.aspectj.ajdoc.PointcutDoc;
27 import org.aspectj.compiler.base.JavaCompiler;
28 import org.aspectj.compiler.base.ast.ASTObject;
29
30 import com.sun.javadoc.ClassDoc;
31 import com.sun.javadoc.ConstructorDoc;
32 import com.sun.javadoc.Doc;
33 import com.sun.javadoc.FieldDoc;
34 import com.sun.javadoc.MemberDoc;
35 import com.sun.javadoc.MethodDoc;
36 import com.sun.javadoc.PackageDoc;
37 import com.sun.javadoc.Parameter;
38 import com.sun.javadoc.SeeTag;
39
40 import java.io.PrintStream JavaDoc;
41 import java.util.ArrayList JavaDoc;
42 import java.util.List JavaDoc;
43 import java.util.Locale JavaDoc;
44 import java.util.StringTokenizer JavaDoc;
45
46 /**
47  * Implementation of see tags in the aspectj-world.
48  * See source for bug comments
49  * @author Jeff Palm
50  */

51 public class SeeTagImpl extends TagImpl implements SeeTag {
52  /*
53  * This implementation handles
54  *<pre>{@link package.class#member label}
55  * @see package.class#member label
56  * @see "some reference"
57  * @see <any tag - should be url></pre>.
58  * It has errors since the tag-separating code which provides
59  * input is wrong, and it's very weak in how it handles
60  * text and URLs. Most of the action is in resolve().
61  */

62
63     /** The package name specified by the user -- may be null. */
64     private String JavaDoc packageName;
65
66     /** The class name specified by the user -- may be null. */
67     private String JavaDoc className;
68
69     /** The member name specified by the user -- may be null. */
70     private String JavaDoc memberName;
71
72     /** The referenced package. */
73     private PackageDoc packageDoc;
74
75     /** The referenced class. */
76     private ClassDoc classDoc;
77
78     /** The referenced member. */
79     private MemberDoc memberDoc;
80
81     /** The label associated with the tag. */
82     private String JavaDoc label = "";
83
84     /** A shared instance of the compiler -- a little hacky. */
85     private static JavaCompiler ajc = AjdocCompiler.instance();
86
87     /**
88      * Constructs the new tag with given parameters and
89      * calls resolve to parse the class, package, and members.
90      *
91      * @param doc the new value for <code>doc</code>.
92      * @param name the new value for <code>name</code>.
93      * @param text the new value for <code>text</code>.
94      * @param locale the new value for <code>locale</code>.
95      * @param err the new value for <code>err</code>.
96      */

97     public SeeTagImpl(Doc doc,
98                       String JavaDoc name,
99                       String JavaDoc text,
100                       Locale JavaDoc loc,
101                       ErrPrinter err) {
102         super(doc, name, text, loc, err);
103         resolve();
104     }
105     
106     /**
107      * Returns the label.
108      *
109      * @return the label.
110      */

111     public String JavaDoc label() {
112         return label;
113     }
114
115     /**
116      * Returns the referenced package's name.
117      * This <b>can</b> be <code>null</code>.
118      *
119      * @return the referenced package's name.
120      */

121     public String JavaDoc referencedPackageName() {
122         return packageName;
123     }
124
125     /**
126      * Returns the referenced package.
127      * This <b>can</b> be <code>null</code>.
128      *
129      * @return a PackageDoc with name packageName.
130      */

131     public PackageDoc referencedPackage() {
132         look();
133         return packageDoc;
134     }
135
136     /**
137      * Returns the referenced class's name.
138      * This <b>can</b> be <code>null</code>.
139      *
140      * @return the referenced class's name.
141      */

142     public String JavaDoc referencedClassName() {
143         return className;
144     }
145
146     /**
147      * Returns the referenced class.
148      * This <b>can</b> be <code>null</code>.
149      *
150      * @return a ClassDoc with name className.
151      */

152     public ClassDoc referencedClass() {
153         look();
154         return classDoc;
155     }
156
157     /**
158      * Returns the referenced members's name.
159      * This <b>can</b> be <code>null</code>.
160      * This can be null.
161      *
162      * @return the referenced class's name.
163      */

164     public String JavaDoc referencedMemberName() {
165         return memberName;
166     }
167
168     /**
169      * Returns the referenced member.
170      * This <b>can</b> be <code>null</code>.
171      *
172      * @return a ClassDoc with name memberName.
173      */

174     public MemberDoc referencedMember() {
175         look();
176         return memberDoc;
177     }
178
179     /**
180      * Returns <code>see</code>.
181      *
182      * @return <code>see</code>.
183      */

184     public String JavaDoc kind() {
185         return "@see";
186     }
187
188     protected JavaCompiler ajc() {
189         if (ajc != null) {
190             return ajc;
191         } else if (doc() instanceof ASTObject) {
192             return ajc = ((ASTObject)doc()).getCompiler();
193         } else if (doc() instanceof PackageDocImpl) {
194             return ajc = ((PackageDocImpl)doc()).ajc();
195         }
196         return null;
197     }
198
199     void debugState(String JavaDoc m, PrintStream JavaDoc err) {
200         if (System.getProperty("seetag.debug") != null) {
201             if (null == err) err = System.err;
202             err.println("\t______________________ " + m
203                                 + "\n\tpackageName: "+packageName
204                                 + "\n\t packageDoc: " +packageDoc
205                                 + "\n\t className: " +className
206                                 + "\n\t classDoc: " +classDoc
207                                 + "\n\t memberName: " +memberName
208                                 + "\n\t memberDoc: " +memberDoc
209                                 + "\n\t label: " +label
210                                 );
211         }
212     }
213     private boolean looked = false;
214     private void look() {
215         if (!looked) {
216             looked = true;
217             dolook();
218         }
219         debugState("SeeTagImpl.look()", null);
220     }
221
222     private void dolook() {
223
224         // For null or empty classnames set the current doc
225
// to the referenced class
226
if (className == null || className.length() < 1) {
227             classDoc = classDoc(doc());
228         } else {
229             
230             // Use the class in which this doc is contained
231
// as a starting point...
232
ClassDoc container = classDoc(doc());
233
234             // ..and try to find the class from there
235
if (container == null) {
236                 //TODO: Find class somewhere else
237
} else {
238                 String JavaDoc fullName;
239                 if (packageName == null || packageName.length() < 1) {
240                     fullName = className;
241                 } else {
242                     fullName = packageName + '.' + className;
243                 }
244
245                 // As per the language spec...
246
// http://java.sun.com/docs/books/jls/second_edition/ (con't)
247
// html/names.doc.html#32725
248
// We must first consider types before identifiers,
249
// therefore, if there is no right parent in the member name
250
// we have to consider this first an inner class, and if
251
// one is found set the member name to nul
252
if (memberName != null &&
253                     memberName.indexOf('(') == -1) {
254                     classDoc = container.findClass(fullName + '.' + memberName);
255
256                     // If we found an inner class, don't look for a member
257
if (classDoc != null) {
258                         memberName = null;
259                     }
260                 }
261
262                 // Now if we didn't find an inner class, just look
263
// up the full name
264
if (classDoc == null) {
265                     classDoc = container.findClass(fullName);
266                 }
267             }
268         }
269
270         // If we found a class, then the package is that
271
// class's contained package
272
if (classDoc != null) {
273             packageDoc = classDoc.containingPackage();
274         } else if (packageName == null) {
275             
276             // If we didn't find a class, but the class name
277
// contains no periods, maybe the class name's really
278
// a package name
279
if (classDoc == null && className != null &&
280                 className.indexOf('.') == -1) {
281                 packageDoc = PackageDocImpl.getPackageDoc(className);
282             }
283             
284             // Otherwise, if the referenced class isn't null, set the
285
// referenced package to that class's contained package
286
else if (classDoc != null) {
287                 packageDoc = classDoc.containingPackage();
288             }
289             
290             // Lastly, if the current doc is a package (i.e. package.html)
291
// then set the referenced package to the current doc
292
else if (doc() instanceof PackageDoc) {
293                 packageDoc = (PackageDoc)doc();
294             }
295         } else {
296             
297             // Look for the fully qualified name of the
298
// package elsewhere
299
packageDoc = PackageDocImpl.getPackageDoc(packageName != null
300                                                       ? packageName
301                                                       : "");
302         }
303
304         // Look for the member if the member name wasn't null
305
if (memberName != null) {
306             lookForMember(memberName, (org.aspectj.ajdoc.ClassDoc)classDoc);
307         }
308     }
309
310     private void lookForMember(String JavaDoc spec,
311                                org.aspectj.ajdoc.ClassDoc container) {
312         int ilparen = spec.indexOf('(');
313         String JavaDoc name;
314         
315         // No parens mean a field or a method
316
// The order is for looking is:
317
// [1] field
318
// [2] method
319
// [3] pointcut
320
if (ilparen == -1) {
321             name = spec;
322             if ((memberDoc = fieldDoc(name, container)) != null) {
323                 return;
324             }
325             if ((memberDoc = methodDoc(name, container, null)) != null) {
326                 return;
327             }
328             if ((memberDoc = pointcutDoc(name, container, null)) != null) {
329                 return;
330             }
331         } else {
332             name = spec.substring(0, ilparen);
333         }
334         int irparen = spec.lastIndexOf(')');
335
336         // Crop out the parameters
337
String JavaDoc paramsString;
338         if (irparen != -1) {
339             paramsString = spec.substring(ilparen+1, irparen);
340         } else {
341             paramsString = spec.substring(ilparen+1, spec.length()-1);
342         }
343
344         // Convert the raw parameters to an array
345
String JavaDoc[] paramNames = paramNames(paramsString);
346
347         // Try to match the name and parameters if the following order:
348
// [1] method
349
// [2] constructor
350
// [3] pointcut
351
// [4] advice
352
if ((memberDoc = methodDoc(name, container, paramNames)) != null) {
353             return;
354         }
355         if ((memberDoc = constructorDoc(container, paramNames)) != null) {
356             return;
357         }
358         if ((memberDoc = pointcutDoc(name, container, paramNames)) != null) {
359             return;
360         }
361         if (container instanceof AspectDoc) {
362             if ((memberDoc = adviceDoc(name,
363                                        (AspectDoc)container,
364                                        paramNames)) != null) {
365                 return;
366             }
367         }
368     }
369
370     private String JavaDoc[] paramNames(String JavaDoc restNoParens) {
371         if (restNoParens == null || restNoParens.length() == 0) {
372             return new String JavaDoc[0];
373         }
374         List JavaDoc params = new ArrayList JavaDoc();
375         for (StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(restNoParens, ",", false);
376              t.hasMoreTokens();) {
377             String JavaDoc spec = t.nextToken().trim();
378             int ispace = spec.indexOf(' ');
379             if (ispace != -1) {
380                 spec = spec.substring(0, ispace);
381             }
382             params.add(spec);
383         }
384         return (String JavaDoc[])params.toArray(new String JavaDoc[params.size()]);
385     }
386
387     private FieldDoc fieldDoc(String JavaDoc name, ClassDoc container) {
388         for (ClassDoc cd = container; cd != null; cd = cd.superclass()) {
389             FieldDoc[] docs = cd.fields();
390             for (int i = 0, N = docs.length; i < N; i++) {
391                 if (docs[i].name().equals(name)) {
392                     return docs[i];
393                 }
394             }
395         }
396         return null;
397     }
398
399     private PointcutDoc pointcutDoc(String JavaDoc name,
400                                     org.aspectj.ajdoc.ClassDoc container,
401                                     String JavaDoc[] paramNames) {
402         if (null == name) return null; // XXX warn or error
403

404         for (org.aspectj.ajdoc.ClassDoc cd = container;
405              cd != null;
406              cd = (org.aspectj.ajdoc.ClassDoc)cd.superclass()) {
407             PointcutDoc[] docs = cd.pointcuts();
408             if (null == docs) {
409                 continue;
410             }
411             for (int i = 0, N = docs.length; i < N; i++) {
412                 PointcutDoc md = docs[i];
413                 if ((null != md)
414                     && (name.equals(md.name()))
415                     && ((null == paramNames)
416                         || parametersMatch(md.parameters(), paramNames, container))) {
417                     return md;
418                 }
419             }
420         }
421         return null;
422     }
423
424     private MethodDoc methodDoc(String JavaDoc name, ClassDoc container,
425                                 String JavaDoc[] paramNames) {
426         for (ClassDoc cd = container; cd != null; cd = cd.superclass()) {
427             MethodDoc[] docs = cd.methods();
428             for (int i = 0, N = docs.length; i < N; i++) {
429                 MethodDoc md = docs[i];
430                 if (!md.name().equals(name)) {
431                     continue;
432                 }
433                 if (paramNames == null) {
434                     return md;
435                 } else {
436                     if (parametersMatch(md.parameters(),
437                                         paramNames,
438                                         container)) {
439                         return md;
440                     }
441                 }
442             }
443         }
444         return null;
445     }
446
447     private ConstructorDoc constructorDoc(ClassDoc container,
448                                           String JavaDoc[] paramNames) {
449         for (ClassDoc cd = container; cd != null; cd = cd.superclass()) {
450             ConstructorDoc[] docs = cd.constructors();
451             for (int i = 0, N = docs.length; i < N; i++) {
452                 ConstructorDoc md = docs[i];
453                 if (paramNames == null) {
454                     return md;
455                 } else {
456                     if (parametersMatch(md.parameters(),
457                                         paramNames,
458                                         container)) {
459                         return md;
460                     }
461                 }
462             }
463         }
464         return null;
465     }
466
467     private AdviceDoc adviceDoc(String JavaDoc name,
468                                 AspectDoc container,
469                                 String JavaDoc[] paramNames) {
470         
471         AspectDoc cd = container;
472         while (cd != null) {
473             AdviceDoc[] docs = cd.advice();
474             for (int i = 0, N = docs.length; i < N; i++) {
475                 AdviceDoc md = docs[i];
476                 if (!(name.equals(md.name()))) {
477                     continue;
478                 }
479                 if (paramNames == null) {
480                     return md;
481                 } else {
482                     if (parametersMatch(md.parameters(),
483                                         paramNames,
484                                         container)) {
485                         return md;
486                     }
487                 }
488             }
489             Object JavaDoc o = cd.superclass();
490             if (o instanceof AspectDoc) {
491                 cd = (AspectDoc) o;
492             } else {
493                 cd = null;
494             }
495         }
496         return null;
497     }
498
499     private boolean parametersMatch(Parameter[] params,
500                                     String JavaDoc[] paramNames,
501                                     ClassDoc container) {
502         if ((null == params) || (null == paramNames) || (null == container)) {
503             return false;
504         }
505         if (params.length != paramNames.length) {
506             return false;
507         }
508         for (int i = 0, N = params.length; i < N; i++) {
509             com.sun.javadoc.Type type1 = params[i].type();
510             com.sun.javadoc.Type type2 = TypeImpl.getInstance(paramNames[i],
511                                                               container);
512             if ((null == type1) || (!type1.equals(type2))) {
513                 return false;
514             }
515         }
516         return true;
517     }
518
519     private ClassDoc classDoc(Doc d) {
520         if (d instanceof ClassDoc) {
521             return (ClassDoc)d;
522         }
523         if (d instanceof MemberDoc) {
524             return ((MemberDoc)d).containingClass();
525         }
526         return null;
527     }
528    
529     /** find next (matching) char x, ignoring instances
530      * preceded by escape character '\'.
531      */

532     private static int findNextChar(final String JavaDoc s, final int start, final char x) { // XXX to Util
533
if ((null != s) && (start >= 0)) {
534             boolean escaped = false;
535             for (int i = start; i < s.length(); i++) {
536                 char c = s.charAt(i);
537                 if (('\\' == c) && !escaped) {
538                     escaped = true;
539                     continue;
540                 } else if ((x == c) && !escaped) {
541                     return i;
542                 }
543                 if (escaped) {
544                     escaped = false;
545                 }
546             }
547         }
548         return -1;
549     }
550     
551     /**
552      * This looks a bit hideous, and it is, I had a state diagram
553      * with every thing labled, but I lost it -- sorry ;).
554      * <pre>{@link package.class#member label} </pre>
555      * http://java.sun.com/j2se/1.3/docs/tooldocs/solaris/javadoc.html#\{@link}
556      */

557     private void resolve() {
558         String JavaDoc str = text();
559
560         if (str == null || str.length() < 1) {
561             return;
562         }
563
564         str = str.trim();
565
566         int N = str.length();
567         
568         char first = str.charAt(0);
569         if (first == '<') {
570             if ((N < 4) || (str.charAt(N-1) != '>')) {
571                 err().error("see_tag_unterminated_url",str);
572             } else {
573                 char second = str.charAt(1);
574                 if ((second == 'a') || (second == 'A')) {
575                     label = str;
576                 } else {
577                     err().error("see_tag_unterminated_url",str); // XXX wrong message
578
}
579             }
580             return;
581         }
582         
583         if (first == '"') {
584             if (N == 1) {
585                 err().error("see_tag_unterminated_string",str);
586             } else if (str.charAt(N-1) == '"') {
587                 label = str;
588             } else {
589                 int loc = findNextChar(str, 1, '"');
590                 if (-1 == loc) {
591                     err().error("see_tag_unterminated_string",str);
592                 } else {
593                     label = str.substring(0, loc+1);
594                 }
595             }
596             return;
597         }
598         // XXX but does not handle URLs?
599
char c = 0;
600         int state = 0, next = 0;
601         boolean finished = false;
602
603         int iclassEnd = -1;
604         int isharp = -1;
605         int ilastDot = -1;
606         int iStartLabel = -1;
607         int iEndMemberLabel = -1; // membername plus parameters
608
boolean sharp = false;
609         int i;
610     done:
611         for (i = 0; i < N; i++, state = next) {
612             c = str.charAt(i);
613             switch (state) {
614                 
615             case 0: // seeking initial: [type|memberName]
616
if (ident(c)) { next = 1; }
617                 else if (c == '#') { next = 2; iclassEnd = i-1; }
618                 else {
619                     err().error("see_tag_dot_sharp_or_id","\""+c+"\"@0",str);
620                     return;
621                 }
622                 break;
623
624             case 1: // reading initial [type|memberName]
625
if (ident(c)) { next = 1; }
626                 else if (c == '#') { next = 2; iclassEnd = i-1; }
627                 else if (c == '.') { next = 3; ilastDot = i; }
628                 else if (space(c)) { iclassEnd = i-1; next = 16; }
629                 else {
630                     err().error("see_tag_invalid_package_or_class","\""+c+"\"@1",str);
631                     return;
632                 }
633                 break;
634                 
635             case 2: // start reading membername (field only?)
636
sharp = true;
637                 if (ident(c)) { next = 4; isharp = i; }
638                 else {
639                     err().error("see_tag_expecting_field_name","\""+c+"\"@2",str);
640                     return;
641                 }
642                 break;
643
644             case 3: // reading qualified type name
645
if (ident(c)) { next = 1; }
646                 else {
647                     err().error("see_tag_invalid_id","\""+c+"\"@3",str);
648                     return;
649                 }
650                 break;
651
652             case 4: // reading membername
653
if (ident(c)) { next = 4; }
654                 else if (space(c)) { next = 13; iEndMemberLabel = i-1;}
655                 else if (c == '(') { next = 15; }
656                 else {
657                     err().error("see_tag_invalid_param_start","\""+c+"\"@4",str);
658                     return;
659                 }
660                 break;
661
662             case 5: // start reading parms
663
if (ident(c)) { next = 6; }
664                 else if (space(c)) { next = 5; }
665                 else if (c == ')') { next = 13; iEndMemberLabel = i;}
666                 else {
667                     err().error("see_tag_premature_param_end","\""+c+"\"@5",str);
668                     return;
669                 }
670                 break;
671
672             case 6: // reading parm (or type?)
673
if (ident(c)) { next = 6; }
674                 else if (c == '.') { next = 7; }
675                 else if (c == '[') { next = 8; }
676                 else if (space(c)) { next = 10; }
677                 else if (c == ',') { next = 12; }
678                 else if (c == ')') { iEndMemberLabel = i; next = 16; }
679                 else {
680                     err().error("see_tag_invalid_parameter_type","\""+c+"\"@6",str);
681                     return;
682                 }
683                 break;
684
685             case 7: // reading qualified parameter type .
686
if (ident(c)) { next = 6; }
687                 else {
688                     err().error("see_tag_invalid_parameter_type_ident","\""+c+"\"@7",str);
689                     return;
690                 }
691                 break;
692
693             case 8: // reading end of []
694
if (c == ']') { next = 9; }
695                 else if (space(c)) { next = 8; }
696                 else {
697                     err().error("see_tag_unterminated_array_type","\""+c+"\"@8",str);
698                     return;
699                 }
700                 break;
701
702             case 9: // maybe completed parameter type
703
if (c == '[') { next = 8; }
704                 else if (space(c)) { next = 10; }
705                 else if (c == ',') { next = 12; }
706                 else if (c == ')') { iEndMemberLabel = i; next = 16; }
707                 else {
708                     err().error("see_tag_invalid_parameter_type","\""+c+"\"@9",str);
709                     return;
710                 }
711                 break;
712
713             case 10: // completed parm type?
714
if (ident(c)) { next = 11; }
715                 else if (space(c)) { next = 12; }
716                 else if (c == ',') { next = 14; }
717                 else if (c == ')') { iEndMemberLabel = i; next = 16; }
718                 else {
719                     err().error("see_tag_invalid_parameters","\""+c+"\"@10",str);
720                     return;
721                 }
722                 break;
723
724             case 11: // reading parm type?
725
if (ident(c)) { next = 11; }
726                 else if (space(c)) { next = 12; }
727                 else if (c == ',') { next = 14; }
728                 else if (c == ')') { iEndMemberLabel = i; next = 16; }
729                  else {
730                     err().error("see_tag_invalid_parameters","\""+c+"\"@11",str);
731                     return;
732                 }
733                 break;
734
735             case 12: // looking for next parm?
736
if (space(c)) { next = 12; }
737                 else if (c == ',') { next = 14; }
738                 else if (ident(c)) { next = 15; }
739                 else if (c == ')') { iEndMemberLabel = i; next = 16; }
740                 else {
741                     err().error("see_tag_invalid_parameters","\""+c+"\"@12",str);
742                     return;
743                 }
744                 break;
745
746             case 13: // seeking parms or label
747
if (space(c)) { next = 13; }
748                 else if (c == '(') { next = 5; } // start reading parms
749
else if (ident(c)) { // start reading label
750
iStartLabel = i; next = 17;
751                  }
752                 else {
753                     err().error("see_tag_invalid_parameters","\""+c+"\"@13",str);
754                     return;
755                 }
756                 break;
757
758             case 14: // type name (or identifier)
759
if (ident(c)) { next = 6; }
760                 else if (space(c)) { next = 14; }
761                 else {
762                     err().error("see_tag_expecting_typename_or_whitespace","\""+c+"\"@14",str);
763                     return;
764                 }
765                 break;
766
767             case 15: // reading parms
768
if (ident(c)) { next = 6; }
769                 else if (space(c)) { next = 15; }
770                 else if (c == ')') { iEndMemberLabel = i; next = 16; }
771                 else {
772                     err().error("see_tag_premature_param_end","\""+c+"\"@15",str);
773                     return;
774                 }
775                 break;
776              case 16 : // seeking label
777
if (ident(c)) { iStartLabel = i; next = 17; }
778                 else if (space(c)) { next = 16; }
779                 else {
780                     String JavaDoc s = "\"" + c + "\" in \"" + text() + "\"";
781                     err().error("see_tag_premature_param_end",s + "@16",str);
782                     return;
783                 }
784                 break;
785              case 17 : // reading label - may have internal spaces
786
if (ident(c)) { next = 17; }
787                 else if (space(c)) { next = 17; }
788                 // XXX known limitation - labels may only be ident + whitespace (no -)
789
else {
790                     err().error("see_tag_premature_param_end","\""+c+"\"@17",str);
791                     return;
792                 }
793                 break;
794             }
795
796             if (i == N-1) {
797                 finished = next == -1
798                     || next == 1 || next == 13
799                     || next == 16 || next == 17
800                     || next == 4 || next == 12;
801             }
802             
803         }
804
805         if (sharp) {
806             if (ilastDot != -1) {
807                 packageName = str.substring(0, ilastDot);
808             }
809         } else {
810             if (ilastDot == -1) {
811                 //packageName = str;
812
} else {
813                 packageName = str.substring(0, ilastDot);
814             }
815         }
816
817         if (sharp) {
818             if (iclassEnd != -1) {
819                 if (ilastDot == -1) {
820                     className = str.substring(0, iclassEnd+1);
821                 } else {
822                     className = str.substring(ilastDot+1, iclassEnd+1);
823                 }
824             }
825         } else {
826             if (ilastDot == -1) {
827                 if (iclassEnd != -1) {
828                     className = str.substring(0, iclassEnd+1);
829                 } else {
830                     className = str;
831                 }
832             } else {
833                 if (iclassEnd != -1) {
834                     className = str.substring(ilastDot+1, iclassEnd+1);
835                 } else {
836                     className = str.substring(ilastDot+1);
837                 }
838             }
839         }
840
841         if (sharp) {
842             if (-1 != iEndMemberLabel) {
843                 memberName = str.substring(isharp, iEndMemberLabel+1).trim();
844             } else {
845                 memberName = str.substring(isharp).trim();
846             }
847             // hack to remove spaces between method name and parms
848
int parmLoc = memberName.indexOf("(");
849             if (-1 != parmLoc) {
850                 int spaceLoc = memberName.indexOf(" ");
851                 if ((-1 != spaceLoc) && (spaceLoc < parmLoc)) {
852                     memberName = memberName.substring(0,spaceLoc)
853                         + memberName.substring(parmLoc).trim();
854                 }
855             }
856         }
857
858         if (!finished) {
859             err().error("see_tag_prematurely_done",str);
860         } else {
861             if (iStartLabel != -1) {
862                 label = str.substring(iStartLabel).trim();
863             } else if (i < N-1) { // when does this happen?
864
label = str.substring(i).trim();
865             }
866         }
867     }
868     
869     // test-only methods
870
String JavaDoc getPackageName() {return packageName;}
871     String JavaDoc getClassName() { return className;}
872     String JavaDoc getMemberName() { return memberName; }
873     String JavaDoc getLabel() { return label; }
874 }
875
Popular Tags