001: /*
002: * CTagger.java
003: *
004: * Copyright (C) 2003 Peter Graves
005: * $Id: ObjCTagger.java,v 1.2 2003/12/30 19:25:17 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 gnu.regexp.RE;
025: import gnu.regexp.UncheckedRE;
026: import java.util.ArrayList;
027:
028: public final class ObjCTagger extends JavaTagger {
029: // States.
030: private static final int NEUTRAL = 0;
031: private static final int METHOD_PROLOG = 1;
032: private static final int METHOD_NAME = 2;
033: private static final int PARAMETER_LIST = 3;
034:
035: private Mode mode = ObjCMode.getMode();
036:
037: public ObjCTagger(SystemBuffer buffer) {
038: super (buffer);
039: }
040:
041: public void run() {
042: ArrayList tags = new ArrayList();
043: pos = new Position(buffer.getFirstLine(), 0);
044: token = null;
045: tokenStart = null;
046: int state = NEUTRAL;
047: while (!pos.atEnd()) {
048: char c = pos.getChar();
049: if (Character.isWhitespace(c)) {
050: pos.skipWhitespace();
051: continue;
052: }
053: if (c == '\'' || c == '"') {
054: pos.skipQuote();
055: continue;
056: }
057: if (pos.lookingAt("/*")) {
058: skipComment(pos);
059: continue;
060: }
061: if (pos.lookingAt("//")) {
062: skipSingleLineComment(pos);
063: continue;
064: }
065: if (c == '#' && pos.getOffset() == 0) {
066: skipPreprocessor(pos);
067: continue;
068: }
069: if (state == METHOD_NAME) {
070: if (c == '{') {
071: if (token != null && !mode.isKeyword(token))
072: tags.add(new CTag(token, tokenStart));
073: skipBrace();
074: state = NEUTRAL;
075: } else if (isIdentifierStart(c)) {
076: state = PARAMETER_LIST;
077: pos.next();
078: } else {
079: state = NEUTRAL;
080: pos.next();
081: }
082: continue;
083: }
084: if (state == PARAMETER_LIST) {
085: if (c == '{') {
086: if (token != null && !mode.isKeyword(token))
087: tags.add(new CTag(token, tokenStart));
088: skipBrace();
089: state = NEUTRAL;
090: continue;
091: } else if (c == '(') {
092: state = NEUTRAL;
093: skipParen();
094: continue;
095: } else {
096: pos.next();
097: continue;
098: }
099: }
100: if (state == METHOD_PROLOG) {
101: if (c == '{') {
102: if (token != null && !mode.isKeyword(token))
103: tags.add(new ObjCTag(token, tokenStart));
104: skipBrace();
105: state = NEUTRAL;
106: continue;
107: } else if (c == '(') {
108: skipParen();
109: continue;
110: } else if (isIdentifierStart(c)) {
111: if (token == null) {
112: tokenStart = pos.copy();
113: token = gatherToken(pos);
114: continue;
115: } else {
116: String s = gatherToken(pos);
117: if (s.endsWith(":"))
118: token = token.concat(s);
119: continue;
120: }
121: }
122: pos.next();
123: continue;
124: }
125: if (c == '}') {
126: pos.next();
127: continue;
128: }
129: if (pos.getOffset() == 0 && (c == '+' || c == '-')) {
130: token = null;
131: state = METHOD_PROLOG;
132: continue;
133: }
134: if (isIdentifierStart(c)) {
135: tokenStart = pos.copy();
136: token = gatherToken(pos);
137: continue;
138: }
139: if (c == '(') {
140: skipParen();
141: state = METHOD_NAME;
142: continue;
143: }
144: pos.next();
145: }
146: buffer.setTags(tags);
147: }
148:
149: private String gatherToken(Position pos) {
150: FastStringBuffer sb = new FastStringBuffer();
151: char c;
152: while (isIdentifierPart(c = pos.getChar()) || c == ':') {
153: sb.append(c);
154: if (!pos.next())
155: break;
156: }
157: return sb.toString();
158: }
159:
160: private static final boolean isIdentifierStart(char c) {
161: return CMode.getMode().isIdentifierStart(c);
162: }
163:
164: private static final boolean isIdentifierPart(char c) {
165: return CMode.getMode().isIdentifierPart(c);
166: }
167: }
|