001: package org.acm.seguin.completer;
002:
003: //import anthelper.JavaUtils;
004: import org.acm.seguin.ide.jedit.Navigator; //import org.acm.segiun.completer;
005: import gnu.regexp.RE;
006: import gnu.regexp.REException;
007: import gnu.regexp.REMatch;
008: import org.gjt.sp.jedit.textarea.JEditTextArea;
009:
010: public class ParseUtils {
011: final static Navigator.NavigatorLogger logger = Navigator
012: .getLogger(ParseUtils.class);
013: final static String RE_PAREN_METHOD_THIS = ".*[^\\w\\.\\$]+\\w+\\s*\\(";
014: final static String RE_PAREN_NEW = "new\\s+\\w+\\s*\\(";
015: final static String RE_PAREN_METHOD = "\\.\\s*\\w+\\s*\\(";
016: final static String RE_CLASS_NEW = ".*[^\\w\\.\\$]+new\\s+\\w*";
017: final static String RE_CLASS_CATCH = "\\s*[}]*\\s*catch\\s*\\(\\w*";
018: final static String RE_CLASS_HELP;
019: static {
020: StringBuffer sb = new StringBuffer();
021: sb.append("(.*\\s+(extends|implements|throws)\\s+.*)");
022: sb.append("|");
023: sb.append("(").append(RE_CLASS_NEW).append(")");
024: sb.append("|");
025: sb.append("(").append(RE_CLASS_CATCH).append(")");
026: RE_CLASS_HELP = sb.toString();
027: }
028:
029: /**
030: * Gets the catchStatement attribute of the ParseUtils class
031: *
032: * @param argLine Description of the Parameter
033: * @return The catchStatement value
034: */
035: public static boolean isCatchStatement(String argLine) {
036: return isMatch(RE_CLASS_CATCH, argLine);
037: }
038:
039: /**
040: * Gets the newClassStatement attribute of the ParseUtils class
041: *
042: * @param argLine Description of the Parameter
043: * @return The newClassStatement value
044: */
045: public static boolean isNewClassStatement(String argLine) {
046: return isMatch(RE_CLASS_NEW, argLine);
047: }
048:
049: /**
050: * Gets the classHelp attribute of the ParseUtils class
051: *
052: * @param argLine Description of the Parameter
053: * @return The classHelp value
054: */
055: public static boolean isClassHelp(String argLine) {
056: return isMatch(RE_CLASS_HELP, argLine);
057: }
058:
059: /**
060: * Gets the codeLine attribute of the ParseUtils object
061: *
062: * @param argTextArea Description of the Parameter
063: * @param startLine Description of the Parameter
064: * @return The codeLine value
065: */
066: public static boolean isCodeLine(JEditTextArea argTextArea,
067: int startLine) {
068: boolean bIsCodeLine = true;
069: String text = argTextArea.getText();
070: int begin = argTextArea.getLineStartOffset(startLine);
071: int end = argTextArea.getCaretPosition();
072: String line = text.substring(begin, end);
073:
074: // check for
075: if (line.indexOf("//") > -1) {
076: // single line comment
077: bIsCodeLine = false;
078: } else if (line.trim().startsWith("import ")
079: || line.trim().startsWith("package ")) {
080: // import export
081: bIsCodeLine = false;
082: } else if (isInQuote(line)) {
083: // double quoted fragement "foo.
084: bIsCodeLine = false;
085: } else {
086: // multi line comment
087: int pos = argTextArea.getCaretPosition();
088: begin = text.lastIndexOf("/*", pos - 1);
089: while (begin > 0 && text.charAt(begin - 1) == '/') {
090: begin = text.lastIndexOf("/*", begin - 1);
091: }
092: end = text.lastIndexOf("*/", pos - 1);
093: if (begin > -1 && end < begin) {
094: bIsCodeLine = false;
095: }
096: }
097: return bIsCodeLine;
098: }
099:
100: static void testInQuote() {
101: String[] strPTests = { "\"foo", "\"foobar'", "\"" };
102:
103: String[] strNTests = { "\"foo\"", "\"foobar'\"", "\"'\"" };
104: for (int i = 0, l = strPTests.length; i < l; i++) {
105: if (!isInQuote(strPTests[i])) {
106: logger.msg("(+) ### FAIL on (" + strPTests[i] + ")");
107: } else {
108: logger.msg("(+) Pass (" + strPTests[i] + ")");
109: }
110: }
111: for (int i = 0, l = strNTests.length; i < l; i++) {
112: if (isInQuote(strNTests[i])) {
113: logger.msg("(-) ### FAIL on (" + strNTests[i] + ")");
114: } else {
115: logger.msg("(-) Pass (" + strNTests[i] + ")");
116: }
117: }
118: }
119:
120: /**
121: * Gets the inQuote attribute of the ParseUtils class
122: *
123: * @param argLine Description of the Parameter
124: * @return The inQuote value
125: */
126: public static boolean isInQuote(String argLine) {
127: boolean bResult = false;
128: boolean bInQuote = false;
129: int iDQ = 0;
130: for (int i = 0, l = argLine.length(); i < l; i++) {
131: switch (argLine.charAt(i)) {
132: case '"':
133: // it's a quote
134: if (bInQuote) {
135: // already found one quote so subtract
136: iDQ++;
137: } else {
138: iDQ--;
139: }
140: bInQuote = !bInQuote;
141: break;
142: case '\\':
143: // skip next char, escape seq
144: i++;
145: break;
146: }
147: }
148: return iDQ != 0;
149: }
150:
151: /**
152: * Gets the inComment attribute of the DotCompleter class
153: *
154: * @param startLine Description of the Parameter
155: * @param argTextArea Description of the Parameter
156: * @return The inComment value
157: */
158: public static boolean isInComment(JEditTextArea argTextArea,
159: int startLine) {
160: boolean bInComment = false;
161: String text = argTextArea.getText();
162: int begin = argTextArea.getLineStartOffset(startLine);
163: int end = argTextArea.getCaretPosition();
164: String line = text.substring(begin, end);
165: if (line.indexOf("//") > -1) {
166: bInComment = true;
167: } else {
168: int pos = argTextArea.getCaretPosition();
169: begin = text.lastIndexOf("/*", pos - 1);
170: while (begin > 0 && text.charAt(begin - 1) == '/') {
171: begin = text.lastIndexOf("/*", begin - 1);
172: }
173: end = text.lastIndexOf("*/", pos - 1);
174: if (begin > -1 && end < begin) {
175: bInComment = true;
176: }
177: }
178: return bInComment;
179: }
180:
181: static REMatch getLastMatch(String argRE, String argText) {
182: REMatch match = null;
183: try {
184: RE re = new RE(argRE);
185: REMatch[] matches = re.getAllMatches(argText);
186: if (matches != null && matches.length > 0) {
187: match = matches[matches.length - 1];
188: }
189: } catch (REException e) {
190: logger.error("Error creating re: " + argRE, e);
191: }
192: return match;
193: }
194:
195: static boolean isValidMatch(REMatch match, int start,
196: int argParenOffset) {
197: if (Completer.DEBUG) {
198: logger.msg("string=(" + match.toString() + "), start=("
199: + match.getStartIndex() + "), end=("
200: + match.getEndIndex() + ")");
201: }
202: return (match != null && start + match.getEndIndex() - 1 == argParenOffset);
203: }
204:
205: static boolean isMatch(String argRE, String argText) {
206: boolean bIsMatch = false;
207: try {
208: RE re = new RE(argRE);
209: bIsMatch = re.isMatch(argText);
210: } catch (REException e) {
211: logger.error("Error creating regexp", e);
212: }
213: return bIsMatch;
214: }
215:
216: static void testREClassHelp() {
217: String[] strPTests = new String[] { " implements ",
218: " extends ", " throws ", " new ", "(new ", ")new ",
219: "+new ", "-new ", "&new ", "/new ", "|new ", "=new ",
220: "<new ", "!new ", ">new ", " new Str", " new String",
221: "catch(", "} catch(", " }catch (", " }catch (NullPo" };
222: String[] strNTests = new String[] { "Aimplements ",
223: "Aextends ", "Athrows ", " new", "$new ", "Anew ",
224: "anew ", "9new ", "_new", ".new ", " new String(" };
225: testRE(RE_CLASS_HELP, strPTests, strNTests);
226: }
227:
228: static void testREParenThisHelp() {
229: String[] strPTests = new String[] { "(toString(",
230: "( toString(", ") toString(", " toString(",
231: "} else if (isClassHelpCase(", "if (isValidMatch(" };
232: String[] strNTests = new String[] { "$toString(" };
233: testRE(RE_PAREN_METHOD_THIS, strPTests, strNTests);
234: }
235:
236: static void testRE(String argRE, String strPTests[],
237: String strNTests[]) {
238: try {
239: logger.msg("start");
240: RE re = new RE(argRE);
241: for (int i = 0, l = strPTests.length; i < l; i++) {
242: if (!re.isMatch(strPTests[i])) {
243: logger.error("+Error testing phrase", strPTests[i]);
244: }
245: }
246: for (int i = 0, l = strNTests.length; i < l; i++) {
247: if (re.isMatch(strNTests[i])) {
248: logger.error("-Error testing phrase", strNTests[i]);
249: }
250: }
251:
252: logger.msg("done");
253: } catch (Exception e) {
254: logger.error("Error testing RE for Class Help", e);
255: }
256: }
257:
258: /**
259: * The main program for the ParseUtils class
260: *
261: * @param args The command line arguments
262: */
263: public static void main(String[] args) {
264: try {
265: testInQuote();
266: } catch (Throwable t) {
267: t.printStackTrace();
268: }
269: }
270: }
|