001: /*
002: * JavaTag.java
003: *
004: * Copyright (C) 2002 Peter Graves
005: * $Id: JavaTag.java,v 1.2 2002/11/10 01:05:48 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j;
023:
024: import java.util.StringTokenizer;
025:
026: public final class JavaTag extends LocalTag {
027: private final JavaClass parent;
028:
029: public JavaTag(String name, Position pos, int type, int flags) {
030: this (name, pos, type, flags, null);
031: }
032:
033: public JavaTag(String name, Position pos, int type, int flags,
034: JavaClass parent) {
035: super (name, pos, type, flags);
036: this .parent = parent;
037: switch (type) {
038: case TAG_METHOD:
039: canonicalSignature = parseCanonicalSignatureForMethod();
040: break;
041: case TAG_EXPLICIT:
042: canonicalSignature = pos.getLine().trim();
043: break;
044: }
045: }
046:
047: public final JavaClass getParent() {
048: return parent;
049: }
050:
051: public String getMethodName() {
052: return getShortName();
053: }
054:
055: private String getShortName() {
056: int index = name.lastIndexOf('.');
057: if (index >= 0)
058: return name.substring(index + 1);
059: else
060: return name;
061: }
062:
063: public String getLongName() {
064: if (name.startsWith("class "))
065: return name;
066: if (canonicalSignature != null)
067: return canonicalSignature;
068: if (getType() == TAG_FIELD) {
069: // Since we don't save information about fields in tag files, we
070: // don't need to initialize a field's canonical signature in the
071: // JavaTag constructor.
072: return canonicalSignature = parseCanonicalSignatureForField();
073: }
074: String s = signature.trim();
075: // Strip comment if any.
076: int index = s.indexOf("//");
077: if (index >= 0)
078: s = s.substring(0, index).trim();
079: index = s.indexOf('=');
080: if (index >= 0)
081: s = s.substring(0, index).trim();
082: index = s.indexOf(';');
083: if (index >= 0)
084: s = s.substring(0, index).trim();
085: return s;
086: }
087:
088: public String getClassName() {
089: if (parent != null)
090: return parent.getName();
091: return null;
092: }
093:
094: private String parseCanonicalSignatureForField() {
095: String s = signature.trim();
096: // Strip comment if any.
097: int index = s.indexOf("//");
098: if (index >= 0)
099: s = s.substring(0, index).trim();
100: // There might be multiple declarations on the same line:
101: // "private int x = 1, y = 2, z = 3;"
102: index = s.indexOf(',');
103: if (index >= 0)
104: s = s.substring(0, index).trim();
105: index = s.indexOf('=');
106: if (index >= 0)
107: s = s.substring(0, index).trim();
108: index = s.indexOf(';');
109: if (index >= 0)
110: s = s.substring(0, index).trim();
111: // If there were multiple declarations on the same line, what we have
112: // now is basically the first of them ("private int x"), even though
113: // we might actually want one of the others. So we copy all but the
114: // last token and then append the short name of this tag. This also
115: // lets us convert tabs to spaces and remove excess whitespace from
116: // the canonical signature.
117: StringTokenizer st = new StringTokenizer(s);
118: int count = st.countTokens();
119: FastStringBuffer sb = new FastStringBuffer();
120: for (int i = 0; i < count - 1; i++) {
121: sb.append(st.nextToken());
122: sb.append(' ');
123: }
124: sb.append(getShortName());
125: return sb.toString();
126: }
127:
128: private String parseCanonicalSignatureForMethod() {
129: FastStringBuffer sb = new FastStringBuffer();
130: Position pos = getPosition().copy();
131: pos.setOffset(0);
132: while (Character.isWhitespace(pos.getChar()))
133: if (!pos.next())
134: return null;
135: char lastChar = 0;
136: char c;
137: while ((c = pos.getChar()) != ')') {
138: if (c == '/') {
139: if (!pos.next())
140: return null;
141: skipComment(pos);
142: if (pos.atEnd())
143: return null;
144: continue;
145: }
146: if (c == '\n' || c == '\t')
147: c = ' ';
148: if (c != ' ' || lastChar != ' ') {
149: sb.append(c);
150: lastChar = c;
151: }
152: if (!pos.next())
153: return null;
154: }
155: if (c == ')')
156: sb.append(c);
157: return sb.toString();
158: }
159:
160: // On entry, pos points at second char of "//" or "/*" (which might not
161: // actually be '/' or '*').
162: private static void skipComment(Position pos) {
163: char c = pos.getChar();
164: if (!pos.next())
165: return;
166: if (c == '/') {
167: while ((c = pos.getChar()) != '\n')
168: if (!pos.next())
169: return;
170: pos.next();
171: } else if (c == '*') {
172: while (!pos.lookingAt("*/"))
173: if (!pos.next())
174: return;
175: pos.skip(2);
176: }
177: }
178:
179: public String getSidebarText() {
180: switch (getType()) {
181: case TAG_EXTENDS:
182: return "extends ".concat(getMethodName());
183: case TAG_IMPLEMENTS:
184: return "implements ".concat(getMethodName());
185: default:
186: return getMethodName();
187: }
188: }
189:
190: public String getToolTipText() {
191: switch (getType()) {
192: case TAG_EXTENDS:
193: return "class ".concat(getMethodName());
194: case TAG_IMPLEMENTS:
195: return "interface ".concat(getMethodName());
196: default:
197: return getLongName();
198: }
199: }
200:
201: public void gotoTag(Editor editor) {
202: switch (getType()) {
203: case TAG_EXTENDS:
204: case TAG_IMPLEMENTS:
205: if (!TagCommands.findClass(editor, getMethodName(), false))
206: super.gotoTag(editor);
207: break;
208: default:
209: super.gotoTag(editor);
210: break;
211: }
212: }
213: }
|