1 21 22 package org.armedbear.j; 23 24 import gnu.regexp.RE; 25 import gnu.regexp.REMatch; 26 import gnu.regexp.UncheckedRE; 27 import java.util.ArrayList ; 28 import java.util.List ; 29 import java.util.Stack ; 30 31 public final class JavaContext implements Constants 32 { 33 private static final boolean DEBUG = false; 34 35 private static final RE parameterRE = 36 new UncheckedRE("^(\\w+\\s+\\w+\\s*,?)"); 37 private static final RE declarationRE = 38 new UncheckedRE("^(\\w+\\s+\\w+\\s*;|\\w+\\s+\\w+\\s*=[^=])"); 39 40 private static final RE returnRE = new UncheckedRE("^return[ \t]"); 42 43 private final Editor editor; 44 private final Stack stack = new Stack (); 45 46 public JavaContext(Editor editor) 47 { 48 this.editor = editor; 49 } 50 51 public void parseContext(Position dot) 52 { 53 final List tags = editor.getBuffer().getTags(); 54 if (tags != null) { 55 Scope scope = new Scope(new Position(editor.getBuffer().getFirstLine(), 0)); 56 stack.push(scope); 57 final int size = tags.size(); 60 for (int i = 0; i < size; i++) { 61 JavaTag tag = (JavaTag) tags.get(i); 62 if (tag.getType() == TAG_FIELD) 63 scope.addField(tag.getSignature()); 64 } 65 } 66 Position pos = findStartOfMethod(dot); 67 if (pos != null) { 68 while (pos.next() && pos.isBefore(dot)) { 69 char c = pos.getChar(); 70 if (c == '(') { 71 Scope scope = new Scope(pos); 72 stack.push(scope); 73 scope.parseParameters(); 74 continue; 75 } 76 if (c == '{') { 77 Scope scope = new Scope(pos); 78 stack.push(scope); 79 scope.parse(dot); 80 break; 81 } 82 } 83 } 84 } 85 86 public JavaVariable findDeclaration(String name) 87 { 88 if (DEBUG) 89 Log.debug("findDeclaration name = |" + name + "|"); 90 if (name == null) 91 return null; 92 int index = name.indexOf('.'); 93 if (index >= 0) { 94 String prefix = name.substring(0, index); 96 if (!prefix.equals("this")) 98 return null; 99 name = name.substring(index+1); 101 if (stack.size() > 0) { 102 Scope scope = (Scope) stack.get(0); 103 for (int j = 0; j < scope.list.size(); j++) { 104 JavaVariable var = scope.getVariable(j); 105 if (name.equals(var.getName())) 106 return var; 107 } 108 } 109 return null; 110 } 111 for (int i = stack.size()-1; i >= 0; i--) { 114 Scope scope = (Scope) stack.get(i); 115 for (int j = 0; j < scope.list.size(); j++) { 116 JavaVariable var = scope.getVariable(j); 117 if (name.equals(var.getName())) 118 return var; 119 } 120 } 121 return null; 122 } 123 124 private Position findStartOfMethod(Position dot) 125 { 126 if (dot != null) { 127 final List tags = editor.getBuffer().getTags(); 128 if (tags != null) { 129 JavaTag tag = null; 130 final int target = dot.lineNumber(); 132 final int limit = tags.size(); 133 for (int i = 0; i < limit; i++) { 134 JavaTag nextTag = (JavaTag) tags.get(i); 135 if (nextTag.lineNumber() > target) 136 break; 137 else 138 tag = nextTag; 139 } 140 if (tag != null && tag.getType() == TAG_METHOD) 141 return tag.getPosition().copy(); 142 } 143 } 144 return null; 145 } 146 147 private final class Scope 148 { 149 final ArrayList list = new ArrayList (); 150 151 final Position start; 152 final Position pos; 153 154 Scope(Position pos) 155 { 156 this.pos = pos; 157 start = pos.copy(); 158 } 159 160 void parse(Position dot) 161 { 162 if (pos.getChar() == '{') { 164 if (!pos.next()) 165 return; 166 } 167 while (pos.isBefore(dot)) { 168 char c = pos.getChar(); 169 if (c == '\'' || c == '"') { 170 pos.skipQuote(); 171 continue; 172 } 173 if (c == '/' && pos.lookingAt("//")) { 174 Line next = pos.getNextLine(); 175 if (next != null) { 176 pos.moveTo(next, 0); 177 continue; 178 } else 179 break; 180 } 181 if (c == '{') { 182 Scope scope = new Scope(pos); 183 stack.push(scope); 184 scope.parse(dot); 185 } else if (c == '}') { 186 stack.pop(); 187 return; 188 } else { 189 final String text = pos.getLine().substring(pos.getOffset()); 190 final REMatch match = declarationRE.getMatch(text); 191 if (match != null) { 192 String s = match.toString(); 193 if (returnRE.getMatch(s) != null) { 194 if (DEBUG) 195 Log.debug("skipping |" + s + "|"); 196 } else 197 addLocalVariable(s); 198 pos.skip(s.length()); 199 continue; 200 } 201 } 202 if (!pos.next()) 203 return; 204 } 205 } 206 207 void parseParameters() 208 { 209 if (pos.getChar() == '(') { 210 if (!pos.next()) 211 return; 212 } 213 FastStringBuffer sb = new FastStringBuffer(); 214 while (!pos.atEnd()) { 215 char c = pos.getChar(); 216 if (c == '\'' || c == '"') { 217 pos.skipQuote(); 218 continue; 219 } 220 if (c == '/') { 221 if (pos.lookingAt("//")) { 222 Line next = pos.getNextLine(); 223 if (next != null) { 224 pos.moveTo(next, 0); 225 continue; 226 } else 227 break; 228 } 229 if (pos.lookingAt("/*")) { 230 pos.skip(2); 231 while (!pos.lookingAt("*/")) { 232 if (!pos.next()) 233 return; 234 } 235 pos.skip(2); 236 continue; 237 } 238 } 239 if (c == ')') 240 break; 241 sb.append(c); 243 if (!pos.next()) 244 break; 245 } 246 String parameters = sb.toString(); 247 while (true) { 248 if (DEBUG) 249 Log.debug("parameters = |" + parameters + "|"); 250 REMatch match = parameterRE.getMatch(parameters); 251 if (match != null) { 252 String s = match.toString(); 253 addParameter(s); 254 parameters = parameters.substring(s.length()).trim(); 255 } else 256 break; 257 } 258 } 259 260 void addField(String signature) 261 { 262 int index = signature.indexOf('='); 263 if (index >= 0) 264 signature = signature.substring(0, index); 265 list.add(new JavaVariable(signature, JavaVariable.FIELD)); 266 } 267 268 void addParameter(String s) 269 { 270 list.add(new JavaVariable(s, JavaVariable.PARAMETER)); 271 } 272 273 void addLocalVariable(String s) 274 { 275 list.add(new JavaVariable(s, JavaVariable.LOCAL)); 276 } 277 278 JavaVariable getVariable(int index) 279 { 280 return (JavaVariable) list.get(index); 281 } 282 283 int getVariableCount() 284 { 285 return list.size(); 286 } 287 288 void dump() 290 { 291 Log.debug("scope at " + start); 292 for (int i = 0; i < list.size(); i++) 293 Log.debug(((JavaVariable)list.get(i)).getName()); 294 } 295 } 296 297 public static void context() 299 { 300 final Editor editor = Editor.currentEditor(); 301 JavaContext context = new JavaContext(editor); 302 context.parseContext(editor.getDot()); 303 Log.debug("--- context at " + editor.getDot() + " ---"); 304 context.dump(); 305 } 306 307 private void dump() 309 { 310 for (int i = 0; i < stack.size(); i++) 311 ((Scope)stack.get(i)).dump(); 312 } 313 } 314 | Popular Tags |