1 package net.sourceforge.phpeclipse.builder;
3 import java.io.BufferedReader;
4 import java.io.FileNotFoundException;
5 import java.io.FileReader;
6 import java.io.FileWriter;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.util.ArrayList;
10 import java.util.Collection;
11 import java.util.HashMap;
12 import java.util.Iterator;
13 import java.util.List;
14 import java.util.StringTokenizer;
16 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
17 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
18 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
19 import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
20 import net.sourceforge.phpeclipse.mover.obfuscator.PHPIdentifier;
22 import org.eclipse.core.resources.IFile;
23 import org.eclipse.core.runtime.CoreException;
26 * Manages the identifer index information for a specific project
29 public class IdentifierIndexManager {
31 public class LineCreator implements ITerminalSymbols {
33 private Scanner fScanner;
36 public LineCreator() {
37 fScanner = new Scanner(false, false);
40 * gets the next token from input
42 private void getNextToken() {
45 fToken = fScanner.getNextToken();
47 int currentEndPosition = fScanner.getCurrentTokenEndPosition();
48 int currentStartPosition = fScanner.getCurrentTokenStartPosition();
50 System.out.print(currentStartPosition + "," + currentEndPosition + ": ");
51 System.out.println(fScanner.toStringAction(fToken));
54 } catch (InvalidInputException e) {
57 fToken = TokenNameERROR;
60 private void parseDeclarations(StringBuffer buf, boolean goBack) {
65 while (fToken != TokenNameEOF && fToken != TokenNameERROR) {
66 if (fToken == TokenNamevar) {
68 if (fToken == TokenNameVariable) {
69 ident = fScanner.getCurrentIdentifierSource();
75 } else if (fToken == TokenNamefunction) {
77 if (fToken == TokenNameAND) {
80 if (fToken == TokenNameIdentifier) {
81 ident = fScanner.getCurrentIdentifierSource();
85 parseDeclarations(buf, true);
87 } else if (fToken == TokenNameclass) {
89 if (fToken == TokenNameIdentifier) {
90 ident = fScanner.getCurrentIdentifierSource();
95 //skip tokens for classname, extends and others until we have the opening '{'
96 while (fToken != TokenNameLBRACE && fToken != TokenNameEOF && fToken != TokenNameERROR) {
99 parseDeclarations(buf, true);
101 } else if (fToken == TokenNamedefine) {
103 if (fToken == TokenNameLPAREN) {
105 if (fToken == TokenNameStringLiteral) {
106 ident = fScanner.getCurrentStringLiteralSource();
112 } else if ((fToken == TokenNameLBRACE) || (fToken == TokenNameDOLLAR_LBRACE)) {
115 } else if (fToken == TokenNameRBRACE) {
118 if (counter == 0 && goBack) {
125 } catch (SyntaxError e) {
126 // TODO Auto-generated catch block
131 public void parseIdentifiers(char[] charArray, StringBuffer buf) {
136 fScanner.setSource(charArray);
137 fScanner.setPHPMode(false);
138 fToken = TokenNameEOF;
142 while (fToken != TokenNameEOF && fToken != TokenNameERROR) {
143 if (fToken == TokenNamefunction) {
145 if (fToken == TokenNameAND) {
148 if (fToken == TokenNameIdentifier) {
149 ident = fScanner.getCurrentIdentifierSource();
153 parseDeclarations(buf, true);
155 } else if (fToken == TokenNameclass) {
157 if (fToken == TokenNameIdentifier) {
158 ident = fScanner.getCurrentIdentifierSource();
163 //skip fTokens for classname, extends and others until we have the opening '{'
164 while (fToken != TokenNameLBRACE && fToken != TokenNameEOF && fToken != TokenNameERROR) {
168 parseDeclarations(buf, true);
171 } else if (fToken == TokenNamedefine) {
173 if (fToken == TokenNameLPAREN) {
175 if (fToken == TokenNameStringLiteral) {
176 ident = fScanner.getCurrentStringLiteralSource();
186 } catch (SyntaxError e) {
187 // TODO Auto-generated catch block
193 private HashMap fFileMap;
194 private String fFilename;
195 private HashMap fIndentifierMap;
197 public IdentifierIndexManager(String filename) {
198 fFilename = filename;
204 * Add the information for a given IFile resource
207 public void addFile(IFile fileToParse) {
209 LineCreator lineCreator = new LineCreator();
211 iStream = fileToParse.getContents();
213 StringBuffer buf = new StringBuffer();
216 while ((c0 = iStream.read()) != (-1)) {
217 buf.append((char) c0);
219 } catch (IOException e) {
223 StringBuffer lineBuffer = new StringBuffer();
224 // lineBuffer.append(fileToParse.getLocation().toString());
225 lineBuffer.append(fileToParse.getFullPath().toString());
226 int lineLength = lineBuffer.length();
227 lineCreator.parseIdentifiers(buf.toString().toCharArray(), lineBuffer);
228 if (lineLength != lineBuffer.length()) {
229 addLine(lineBuffer.toString());
231 } catch (CoreException e1) {
232 // TODO Auto-generated catch block
233 e1.printStackTrace();
238 * Adds a line of the index file for function, class, class-method and class-variable names
242 private void addLine(String line) {
243 StringTokenizer tokenizer;
244 String phpFileName = null;
246 String identifier = null;
247 String classname = null;
248 PHPIdentifier phpIdentifier = null;
249 boolean tokenExists = false;
251 tokenizer = new StringTokenizer(line, "\t");
252 // first token contains the filename:
253 if (tokenizer.hasMoreTokens()) {
254 phpFileName = tokenizer.nextToken();
255 //System.out.println(token);
259 // all the other tokens are identifiers:
260 while (tokenizer.hasMoreTokens()) {
261 token = tokenizer.nextToken();
262 //System.out.println(token);
263 switch (token.charAt(0)) {
264 case 'c' : // class name
265 identifier = token.substring(1);
266 classname = identifier;
267 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.CLASS, phpFileName);
270 identifier = token.substring(1);
271 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.DEFINE, phpFileName);
273 case 'f' : // function name
274 identifier = token.substring(1);
275 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.FUNCTION, phpFileName);
277 case 'm' : //method inside a class
278 identifier = token.substring(1);
279 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.METHOD, phpFileName, classname);
281 case 'v' : // variable inside a class
282 identifier = token.substring(1);
283 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.VARIABLE, phpFileName, classname);
287 phpIdentifier = null;
290 if (identifier != null && phpIdentifier != null) {
292 ArrayList list = (ArrayList) fIndentifierMap.get(identifier);
294 list = new ArrayList();
295 list.add(phpIdentifier);
296 fIndentifierMap.put(identifier, list);
298 boolean flag = false;
299 for (int i = 0; i < list.size(); i++) {
300 if (list.get(i).equals(phpIdentifier)) {
306 list.add(phpIdentifier);
312 fFileMap.put(phpFileName, line);
317 * Change the information for a given IFile resource
320 public void changeFile(IFile fileToParse) {
321 removeFile(fileToParse);
322 addFile(fileToParse);
326 * Get a list of all PHPIdentifierLocation object's associated with an identifier
331 public List getLocations(String identifier) {
332 return (List) fIndentifierMap.get(identifier);
336 * Initialize (i.e. clear) the current index information
339 public void initialize() {
340 fIndentifierMap = new HashMap();
341 fFileMap = new HashMap();
344 private void readFile() {
346 FileReader fileReader;
348 fileReader = new FileReader(fFilename);
350 BufferedReader bufferedReader = new BufferedReader(fileReader);
353 while (bufferedReader.ready()) {
354 // all entries for one file are in a line
355 // separated by tabs !
356 line = bufferedReader.readLine();
361 } catch (FileNotFoundException e) {
363 // TODO DialogBox which asks the user if she/he likes to build new index?
364 } catch (IOException e) {
365 // TODO Auto-generated catch block
372 * Remove the information for a given IFile resource
375 public void removeFile(IFile fileToParse) {
376 // String line = (String) fFileMap.get(fileToParse.getLocation().toString());
377 String line = (String) fFileMap.get(fileToParse.getFullPath().toString());
384 * Removes a line of the index file for function, class, class-method and class-variable names
388 private void removeLine(String line) {
389 StringTokenizer tokenizer;
390 String phpFileName = null;
392 String identifier = null;
393 String classname = null;
394 PHPIdentifier phpIdentifier = null;
395 boolean tokenExists = false;
397 tokenizer = new StringTokenizer(line, "\t");
398 // first token contains the filename:
399 if (tokenizer.hasMoreTokens()) {
400 phpFileName = tokenizer.nextToken();
401 //System.out.println(token);
405 // all the other tokens are identifiers:
406 while (tokenizer.hasMoreTokens()) {
407 token = tokenizer.nextToken();
408 //System.out.println(token);
409 switch (token.charAt(0)) {
410 case 'c' : // class name
411 identifier = token.substring(1);
412 classname = identifier;
413 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.CLASS, phpFileName);
416 identifier = token.substring(1);
417 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.DEFINE, phpFileName);
419 case 'f' : // function name
420 identifier = token.substring(1);
421 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.FUNCTION, phpFileName);
423 case 'm' : //method inside a class
424 identifier = token.substring(1);
425 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.METHOD, phpFileName, classname);
427 case 'v' : // variable inside a class
428 identifier = token.substring(1);
429 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.VARIABLE, phpFileName, classname);
433 phpIdentifier = null;
436 if (identifier != null && phpIdentifier != null) {
437 ArrayList list = (ArrayList) fIndentifierMap.get(identifier);
440 for (int i = 0; i < list.size(); i++) {
441 if (list.get(i).equals(phpIdentifier)) {
446 if (list.size() == 0) {
447 fIndentifierMap.remove(identifier);
452 fFileMap.remove(phpFileName);
456 * Save the current index information in the projects index file
459 public void writeFile() {
460 FileWriter fileWriter;
462 fileWriter = new FileWriter(fFilename);
464 Collection collection = fFileMap.values();
465 Iterator iterator = collection.iterator();
466 while (iterator.hasNext()) {
467 line = (String) iterator.next();
468 fileWriter.write(line + '\n');
471 } catch (IOException e) {
472 // TODO Auto-generated catch block