src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java

Thu, 31 Aug 2017 15:17:03 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:17:03 +0800
changeset 2525
2eb010b6cb22
parent 1409
33abf479f202
parent 0
959103a6100f
child 3932
b8a6df910f59
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.tools.javadoc;
aoqi@0 27
aoqi@0 28 import java.io.File;
aoqi@0 29 import java.util.Locale;
aoqi@0 30
aoqi@0 31 import com.sun.javadoc.*;
aoqi@0 32 import com.sun.tools.javac.code.Kinds;
aoqi@0 33 import com.sun.tools.javac.code.Printer;
aoqi@0 34 import com.sun.tools.javac.code.Symbol;
aoqi@0 35 import com.sun.tools.javac.code.Type.CapturedType;
aoqi@0 36 import com.sun.tools.javac.util.*;
aoqi@0 37
aoqi@0 38 /**
aoqi@0 39 * Represents a see also documentation tag.
aoqi@0 40 * The @see tag can be plain text, or reference a class or member.
aoqi@0 41 *
aoqi@0 42 * <p><b>This is NOT part of any supported API.
aoqi@0 43 * If you write code that depends on this, you do so at your own risk.
aoqi@0 44 * This code and its internal interfaces are subject to change or
aoqi@0 45 * deletion without notice.</b>
aoqi@0 46 *
aoqi@0 47 * @author Kaiyang Liu (original)
aoqi@0 48 * @author Robert Field (rewrite)
aoqi@0 49 * @author Atul M Dambalkar
aoqi@0 50 *
aoqi@0 51 */
aoqi@0 52 class SeeTagImpl extends TagImpl implements SeeTag, LayoutCharacters {
aoqi@0 53
aoqi@0 54 //### TODO: Searching for classes, fields, and methods
aoqi@0 55 //### should follow the normal rules applied by the compiler.
aoqi@0 56
aoqi@0 57 /**
aoqi@0 58 * where of where#what - i.e. the class name (may be empty)
aoqi@0 59 */
aoqi@0 60 private String where;
aoqi@0 61
aoqi@0 62 /**
aoqi@0 63 * what of where#what - i.e. the member (may be null)
aoqi@0 64 */
aoqi@0 65 private String what;
aoqi@0 66
aoqi@0 67 private PackageDoc referencedPackage;
aoqi@0 68 private ClassDoc referencedClass;
aoqi@0 69 private MemberDoc referencedMember;
aoqi@0 70
aoqi@0 71 String label = "";
aoqi@0 72
aoqi@0 73 SeeTagImpl(DocImpl holder, String name, String text) {
aoqi@0 74 super(holder, name, text);
aoqi@0 75 parseSeeString();
aoqi@0 76 if (where != null) {
aoqi@0 77 ClassDocImpl container = null;
aoqi@0 78 if (holder instanceof MemberDoc) {
aoqi@0 79 container =
aoqi@0 80 (ClassDocImpl)((ProgramElementDoc)holder).containingClass();
aoqi@0 81 } else if (holder instanceof ClassDoc) {
aoqi@0 82 container = (ClassDocImpl)holder;
aoqi@0 83 }
aoqi@0 84 findReferenced(container);
aoqi@0 85 if (showRef) showRef();
aoqi@0 86 }
aoqi@0 87 }
aoqi@0 88
aoqi@0 89 private static final boolean showRef = false;
aoqi@0 90
aoqi@0 91 private void showRef() {
aoqi@0 92 Symbol sym;
aoqi@0 93 if (referencedMember != null) {
aoqi@0 94 if (referencedMember instanceof MethodDocImpl)
aoqi@0 95 sym = ((MethodDocImpl) referencedMember).sym;
aoqi@0 96 else if (referencedMember instanceof FieldDocImpl)
aoqi@0 97 sym = ((FieldDocImpl) referencedMember).sym;
aoqi@0 98 else
aoqi@0 99 sym = ((ConstructorDocImpl) referencedMember).sym;
aoqi@0 100 } else if (referencedClass != null) {
aoqi@0 101 sym = ((ClassDocImpl) referencedClass).tsym;
aoqi@0 102 } else if (referencedPackage != null) {
aoqi@0 103 sym = ((PackageDocImpl) referencedPackage).sym;
aoqi@0 104 } else
aoqi@0 105 return;
aoqi@0 106
aoqi@0 107 final JavacMessages messages = JavacMessages.instance(docenv().context);
aoqi@0 108 Locale locale = Locale.getDefault();
aoqi@0 109 Printer printer = new Printer() {
aoqi@0 110 int count;
aoqi@0 111 @Override
aoqi@0 112 protected String localize(Locale locale, String key, Object... args) {
aoqi@0 113 return messages.getLocalizedString(locale, key, args);
aoqi@0 114 }
aoqi@0 115 @Override
aoqi@0 116 protected String capturedVarId(CapturedType t, Locale locale) {
aoqi@0 117 return "CAP#" + (++count);
aoqi@0 118 }
aoqi@0 119 };
aoqi@0 120
aoqi@0 121 String s = text.replaceAll("\\s+", " "); // normalize white space
aoqi@0 122 int sp = s.indexOf(" ");
aoqi@0 123 int lparen = s.indexOf("(");
aoqi@0 124 int rparen = s.indexOf(")");
aoqi@0 125 String seetext = (sp == -1) ? s
aoqi@0 126 : (lparen == -1 || sp < lparen) ? s.substring(0, sp)
aoqi@0 127 : s.substring(0, rparen + 1);
aoqi@0 128
aoqi@0 129 File file = new File(holder.position().file().getAbsoluteFile().toURI().normalize());
aoqi@0 130
aoqi@0 131 StringBuilder sb = new StringBuilder();
aoqi@0 132 sb.append("+++ ").append(file).append(": ")
aoqi@0 133 .append(name()).append(" ").append(seetext).append(": ");
aoqi@0 134 sb.append(sym.getKind()).append(" ");
aoqi@0 135 if (sym.kind == Kinds.MTH || sym.kind == Kinds.VAR)
aoqi@0 136 sb.append(printer.visit(sym.owner, locale)).append(".");
aoqi@0 137 sb.append(printer.visit(sym, locale));
aoqi@0 138
aoqi@0 139 System.err.println(sb);
aoqi@0 140 }
aoqi@0 141
aoqi@0 142 /**
aoqi@0 143 * get the class name part of @see, For instance,
aoqi@0 144 * if the comment is @see String#startsWith(java.lang.String) .
aoqi@0 145 * This function returns String.
aoqi@0 146 * Returns null if format was not that of java reference.
aoqi@0 147 * Return empty string if class name was not specified..
aoqi@0 148 */
aoqi@0 149 public String referencedClassName() {
aoqi@0 150 return where;
aoqi@0 151 }
aoqi@0 152
aoqi@0 153 /**
aoqi@0 154 * get the package referenced by @see. For instance,
aoqi@0 155 * if the comment is @see java.lang
aoqi@0 156 * This function returns a PackageDocImpl for java.lang
aoqi@0 157 * Returns null if no known package found.
aoqi@0 158 */
aoqi@0 159 public PackageDoc referencedPackage() {
aoqi@0 160 return referencedPackage;
aoqi@0 161 }
aoqi@0 162
aoqi@0 163 /**
aoqi@0 164 * get the class referenced by the class name part of @see, For instance,
aoqi@0 165 * if the comment is @see String#startsWith(java.lang.String) .
aoqi@0 166 * This function returns a ClassDocImpl for java.lang.String.
aoqi@0 167 * Returns null if class is not a class specified on the javadoc command line..
aoqi@0 168 */
aoqi@0 169 public ClassDoc referencedClass() {
aoqi@0 170 return referencedClass;
aoqi@0 171 }
aoqi@0 172
aoqi@0 173 /**
aoqi@0 174 * get the name of the member referenced by the prototype part of @see,
aoqi@0 175 * For instance,
aoqi@0 176 * if the comment is @see String#startsWith(java.lang.String) .
aoqi@0 177 * This function returns "startsWith(java.lang.String)"
aoqi@0 178 * Returns null if format was not that of java reference.
aoqi@0 179 * Return empty string if member name was not specified..
aoqi@0 180 */
aoqi@0 181 public String referencedMemberName() {
aoqi@0 182 return what;
aoqi@0 183 }
aoqi@0 184
aoqi@0 185 /**
aoqi@0 186 * get the member referenced by the prototype part of @see,
aoqi@0 187 * For instance,
aoqi@0 188 * if the comment is @see String#startsWith(java.lang.String) .
aoqi@0 189 * This function returns a MethodDocImpl for startsWith.
aoqi@0 190 * Returns null if member could not be determined.
aoqi@0 191 */
aoqi@0 192 public MemberDoc referencedMember() {
aoqi@0 193 return referencedMember;
aoqi@0 194 }
aoqi@0 195
aoqi@0 196
aoqi@0 197 /**
aoqi@0 198 * parse @see part of comment. Determine 'where' and 'what'
aoqi@0 199 */
aoqi@0 200 private void parseSeeString() {
aoqi@0 201 int len = text.length();
aoqi@0 202 if (len == 0) {
aoqi@0 203 return;
aoqi@0 204 }
aoqi@0 205 switch (text.charAt(0)) {
aoqi@0 206 case '<':
aoqi@0 207 if (text.charAt(len-1) != '>') {
aoqi@0 208 docenv().warning(holder,
aoqi@0 209 "tag.see.no_close_bracket_on_url",
aoqi@0 210 name, text);
aoqi@0 211 }
aoqi@0 212 return;
aoqi@0 213 case '"':
aoqi@0 214 if (len == 1 || text.charAt(len-1) != '"') {
aoqi@0 215 docenv().warning(holder,
aoqi@0 216 "tag.see.no_close_quote",
aoqi@0 217 name, text);
aoqi@0 218 } else {
aoqi@0 219 // text = text.substring(1,len-1); // strip quotes
aoqi@0 220 }
aoqi@0 221 return;
aoqi@0 222 }
aoqi@0 223
aoqi@0 224 // check that the text is one word, with possible parentheses
aoqi@0 225 // this part of code doesn't allow
aoqi@0 226 // @see <a href=.....>asfd</a>
aoqi@0 227 // comment it.
aoqi@0 228
aoqi@0 229 // the code assumes that there is no initial white space.
aoqi@0 230 int parens = 0;
aoqi@0 231 int commentstart = 0;
aoqi@0 232 int start = 0;
aoqi@0 233 int cp;
aoqi@0 234 for (int i = start; i < len ; i += Character.charCount(cp)) {
aoqi@0 235 cp = text.codePointAt(i);
aoqi@0 236 switch (cp) {
aoqi@0 237 case '(': parens++; break;
aoqi@0 238 case ')': parens--; break;
aoqi@0 239 case '[': case ']': case '.': case '#': break;
aoqi@0 240 case ',':
aoqi@0 241 if (parens <= 0) {
aoqi@0 242 docenv().warning(holder,
aoqi@0 243 "tag.see.malformed_see_tag",
aoqi@0 244 name, text);
aoqi@0 245 return;
aoqi@0 246 }
aoqi@0 247 break;
aoqi@0 248 case ' ': case '\t': case '\n': case CR:
aoqi@0 249 if (parens == 0) { //here onwards the comment starts.
aoqi@0 250 commentstart = i;
aoqi@0 251 i = len;
aoqi@0 252 }
aoqi@0 253 break;
aoqi@0 254 default:
aoqi@0 255 if (!Character.isJavaIdentifierPart(cp)) {
aoqi@0 256 docenv().warning(holder,
aoqi@0 257 "tag.see.illegal_character",
aoqi@0 258 name, ""+cp, text);
aoqi@0 259 }
aoqi@0 260 break;
aoqi@0 261 }
aoqi@0 262 }
aoqi@0 263 if (parens != 0) {
aoqi@0 264 docenv().warning(holder,
aoqi@0 265 "tag.see.malformed_see_tag",
aoqi@0 266 name, text);
aoqi@0 267 return;
aoqi@0 268 }
aoqi@0 269
aoqi@0 270 String seetext = "";
aoqi@0 271 String labeltext = "";
aoqi@0 272
aoqi@0 273 if (commentstart > 0) {
aoqi@0 274 seetext = text.substring(start, commentstart);
aoqi@0 275 labeltext = text.substring(commentstart + 1);
aoqi@0 276 // strip off the white space which can be between seetext and the
aoqi@0 277 // actual label.
aoqi@0 278 for (int i = 0; i < labeltext.length(); i++) {
aoqi@0 279 char ch2 = labeltext.charAt(i);
aoqi@0 280 if (!(ch2 == ' ' || ch2 == '\t' || ch2 == '\n')) {
aoqi@0 281 label = labeltext.substring(i);
aoqi@0 282 break;
aoqi@0 283 }
aoqi@0 284 }
aoqi@0 285 } else {
aoqi@0 286 seetext = text;
aoqi@0 287 label = "";
aoqi@0 288 }
aoqi@0 289
aoqi@0 290 int sharp = seetext.indexOf('#');
aoqi@0 291 if (sharp >= 0) {
aoqi@0 292 // class#member
aoqi@0 293 where = seetext.substring(0, sharp);
aoqi@0 294 what = seetext.substring(sharp + 1);
aoqi@0 295 } else {
aoqi@0 296 if (seetext.indexOf('(') >= 0) {
aoqi@0 297 docenv().warning(holder,
aoqi@0 298 "tag.see.missing_sharp",
aoqi@0 299 name, text);
aoqi@0 300 where = "";
aoqi@0 301 what = seetext;
aoqi@0 302 }
aoqi@0 303 else {
aoqi@0 304 // no member specified, text names class
aoqi@0 305 where = seetext;
aoqi@0 306 what = null;
aoqi@0 307 }
aoqi@0 308 }
aoqi@0 309 }
aoqi@0 310
aoqi@0 311 /**
aoqi@0 312 * Find what is referenced by the see also. If possible, sets
aoqi@0 313 * referencedClass and referencedMember.
aoqi@0 314 *
aoqi@0 315 * @param containingClass the class containing the comment containing
aoqi@0 316 * the tag. May be null, if, for example, it is a package comment.
aoqi@0 317 */
aoqi@0 318 private void findReferenced(ClassDocImpl containingClass) {
aoqi@0 319 if (where.length() > 0) {
aoqi@0 320 if (containingClass != null) {
aoqi@0 321 referencedClass = containingClass.findClass(where);
aoqi@0 322 } else {
aoqi@0 323 referencedClass = docenv().lookupClass(where);
aoqi@0 324 }
aoqi@0 325 if (referencedClass == null && holder() instanceof ProgramElementDoc) {
aoqi@0 326 referencedClass = docenv().lookupClass(
aoqi@0 327 ((ProgramElementDoc) holder()).containingPackage().name() + "." + where);
aoqi@0 328 }
aoqi@0 329
aoqi@0 330 if (referencedClass == null) { /* may just not be in this run */
aoqi@0 331 // check if it's a package name
aoqi@0 332 referencedPackage = docenv().lookupPackage(where);
aoqi@0 333 return;
aoqi@0 334 }
aoqi@0 335 } else {
aoqi@0 336 if (containingClass == null) {
aoqi@0 337 docenv().warning(holder,
aoqi@0 338 "tag.see.class_not_specified",
aoqi@0 339 name, text);
aoqi@0 340 return;
aoqi@0 341 } else {
aoqi@0 342 referencedClass = containingClass;
aoqi@0 343 }
aoqi@0 344 }
aoqi@0 345 where = referencedClass.qualifiedName();
aoqi@0 346
aoqi@0 347 if (what == null) {
aoqi@0 348 return;
aoqi@0 349 } else {
aoqi@0 350 int paren = what.indexOf('(');
aoqi@0 351 String memName = (paren >= 0 ? what.substring(0, paren) : what);
aoqi@0 352 String[] paramarr;
aoqi@0 353 if (paren > 0) {
aoqi@0 354 // has parameter list -- should be method or constructor
aoqi@0 355 paramarr = new ParameterParseMachine(what.
aoqi@0 356 substring(paren, what.length())).parseParameters();
aoqi@0 357 if (paramarr != null) {
aoqi@0 358 referencedMember = findExecutableMember(memName, paramarr,
aoqi@0 359 referencedClass);
aoqi@0 360 } else {
aoqi@0 361 referencedMember = null;
aoqi@0 362 }
aoqi@0 363 } else {
aoqi@0 364 // no parameter list -- should be field
aoqi@0 365 referencedMember = findExecutableMember(memName, null,
aoqi@0 366 referencedClass);
aoqi@0 367 FieldDoc fd = ((ClassDocImpl)referencedClass).
aoqi@0 368 findField(memName);
aoqi@0 369 // when no args given, prefer fields over methods
aoqi@0 370 if (referencedMember == null ||
aoqi@0 371 (fd != null &&
aoqi@0 372 fd.containingClass()
aoqi@0 373 .subclassOf(referencedMember.containingClass()))) {
aoqi@0 374 referencedMember = fd;
aoqi@0 375 }
aoqi@0 376 }
aoqi@0 377 if (referencedMember == null) {
aoqi@0 378 docenv().warning(holder,
aoqi@0 379 "tag.see.can_not_find_member",
aoqi@0 380 name, what, where);
aoqi@0 381 }
aoqi@0 382 }
aoqi@0 383 }
aoqi@0 384
aoqi@0 385 private MemberDoc findReferencedMethod(String memName, String[] paramarr,
aoqi@0 386 ClassDoc referencedClass) {
aoqi@0 387 MemberDoc meth = findExecutableMember(memName, paramarr, referencedClass);
aoqi@0 388 ClassDoc[] nestedclasses = referencedClass.innerClasses();
aoqi@0 389 if (meth == null) {
aoqi@0 390 for (int i = 0; i < nestedclasses.length; i++) {
aoqi@0 391 meth = findReferencedMethod(memName, paramarr, nestedclasses[i]);
aoqi@0 392 if (meth != null) {
aoqi@0 393 return meth;
aoqi@0 394 }
aoqi@0 395 }
aoqi@0 396 }
aoqi@0 397 return null;
aoqi@0 398 }
aoqi@0 399
aoqi@0 400 private MemberDoc findExecutableMember(String memName, String[] paramarr,
aoqi@0 401 ClassDoc referencedClass) {
aoqi@0 402 if (memName.equals(referencedClass.name())) {
aoqi@0 403 return ((ClassDocImpl)referencedClass).findConstructor(memName,
aoqi@0 404 paramarr);
aoqi@0 405 } else { // it's a method.
aoqi@0 406 return ((ClassDocImpl)referencedClass).findMethod(memName,
aoqi@0 407 paramarr);
aoqi@0 408 }
aoqi@0 409 }
aoqi@0 410
aoqi@0 411 // separate "int, String" from "(int, String)"
aoqi@0 412 // (int i, String s) ==> [0] = "int", [1] = String
aoqi@0 413 // (int[][], String[]) ==> [0] = "int[][]" // [1] = "String[]"
aoqi@0 414 class ParameterParseMachine {
aoqi@0 415 static final int START = 0;
aoqi@0 416 static final int TYPE = 1;
aoqi@0 417 static final int NAME = 2;
aoqi@0 418 static final int TNSPACE = 3; // space between type and name
aoqi@0 419 static final int ARRAYDECORATION = 4;
aoqi@0 420 static final int ARRAYSPACE = 5;
aoqi@0 421
aoqi@0 422 String parameters;
aoqi@0 423
aoqi@0 424 StringBuilder typeId;
aoqi@0 425
aoqi@0 426 ListBuffer<String> paramList;
aoqi@0 427
aoqi@0 428 ParameterParseMachine(String parameters) {
aoqi@0 429 this.parameters = parameters;
aoqi@0 430 this.paramList = new ListBuffer<String>();
aoqi@0 431 typeId = new StringBuilder();
aoqi@0 432 }
aoqi@0 433
aoqi@0 434 public String[] parseParameters() {
aoqi@0 435 if (parameters.equals("()")) {
aoqi@0 436 return new String[0];
aoqi@0 437 } // now strip off '(' and ')'
aoqi@0 438 int state = START;
aoqi@0 439 int prevstate = START;
aoqi@0 440 parameters = parameters.substring(1, parameters.length() - 1);
aoqi@0 441 int cp;
aoqi@0 442 for (int index = 0; index < parameters.length(); index += Character.charCount(cp)) {
aoqi@0 443 cp = parameters.codePointAt(index);
aoqi@0 444 switch (state) {
aoqi@0 445 case START:
aoqi@0 446 if (Character.isJavaIdentifierStart(cp)) {
aoqi@0 447 typeId.append(Character.toChars(cp));
aoqi@0 448 state = TYPE;
aoqi@0 449 }
aoqi@0 450 prevstate = START;
aoqi@0 451 break;
aoqi@0 452 case TYPE:
aoqi@0 453 if (Character.isJavaIdentifierPart(cp) || cp == '.') {
aoqi@0 454 typeId.append(Character.toChars(cp));
aoqi@0 455 } else if (cp == '[') {
aoqi@0 456 typeId.append('[');
aoqi@0 457 state = ARRAYDECORATION;
aoqi@0 458 } else if (Character.isWhitespace(cp)) {
aoqi@0 459 state = TNSPACE;
aoqi@0 460 } else if (cp == ',') { // no name, just type
aoqi@0 461 addTypeToParamList();
aoqi@0 462 state = START;
aoqi@0 463 }
aoqi@0 464 prevstate = TYPE;
aoqi@0 465 break;
aoqi@0 466 case TNSPACE:
aoqi@0 467 if (Character.isJavaIdentifierStart(cp)) { // name
aoqi@0 468 if (prevstate == ARRAYDECORATION) {
aoqi@0 469 docenv().warning(holder,
aoqi@0 470 "tag.missing_comma_space",
aoqi@0 471 name,
aoqi@0 472 "(" + parameters + ")");
aoqi@0 473 return (String[])null;
aoqi@0 474 }
aoqi@0 475 addTypeToParamList();
aoqi@0 476 state = NAME;
aoqi@0 477 } else if (cp == '[') {
aoqi@0 478 typeId.append('[');
aoqi@0 479 state = ARRAYDECORATION;
aoqi@0 480 } else if (cp == ',') { // just the type
aoqi@0 481 addTypeToParamList();
aoqi@0 482 state = START;
aoqi@0 483 } // consume rest all
aoqi@0 484 prevstate = TNSPACE;
aoqi@0 485 break;
aoqi@0 486 case ARRAYDECORATION:
aoqi@0 487 if (cp == ']') {
aoqi@0 488 typeId.append(']');
aoqi@0 489 state = TNSPACE;
aoqi@0 490 } else if (!Character.isWhitespace(cp)) {
aoqi@0 491 docenv().warning(holder,
aoqi@0 492 "tag.illegal_char_in_arr_dim",
aoqi@0 493 name,
aoqi@0 494 "(" + parameters + ")");
aoqi@0 495 return (String[])null;
aoqi@0 496 }
aoqi@0 497 prevstate = ARRAYDECORATION;
aoqi@0 498 break;
aoqi@0 499 case NAME:
aoqi@0 500 if (cp == ',') { // just consume everything till ','
aoqi@0 501 state = START;
aoqi@0 502 }
aoqi@0 503 prevstate = NAME;
aoqi@0 504 break;
aoqi@0 505 }
aoqi@0 506 }
aoqi@0 507 if (state == ARRAYDECORATION ||
aoqi@0 508 (state == START && prevstate == TNSPACE)) {
aoqi@0 509 docenv().warning(holder,
aoqi@0 510 "tag.illegal_see_tag",
aoqi@0 511 "(" + parameters + ")");
aoqi@0 512 }
aoqi@0 513 if (typeId.length() > 0) {
aoqi@0 514 paramList.append(typeId.toString());
aoqi@0 515 }
aoqi@0 516 return paramList.toArray(new String[paramList.length()]);
aoqi@0 517 }
aoqi@0 518
aoqi@0 519 void addTypeToParamList() {
aoqi@0 520 if (typeId.length() > 0) {
aoqi@0 521 paramList.append(typeId.toString());
aoqi@0 522 typeId.setLength(0);
aoqi@0 523 }
aoqi@0 524 }
aoqi@0 525 }
aoqi@0 526
aoqi@0 527 /**
aoqi@0 528 * Return the kind of this tag.
aoqi@0 529 */
aoqi@0 530 @Override
aoqi@0 531 public String kind() {
aoqi@0 532 return "@see";
aoqi@0 533 }
aoqi@0 534
aoqi@0 535 /**
aoqi@0 536 * Return the label of the see tag.
aoqi@0 537 */
aoqi@0 538 public String label() {
aoqi@0 539 return label;
aoqi@0 540 }
aoqi@0 541 }

mercurial