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 == TokenNameLBRACE) || (fToken == TokenNameDOLLAR_LBRACE)) {
104 } else if (fToken == TokenNameRBRACE) {
107 if (counter == 0 && goBack) {
114 } catch (SyntaxError e) {
115 // TODO Auto-generated catch block
120 public void parseIdentifiers(char[] charArray, StringBuffer buf) {
125 fScanner.setSource(charArray);
126 fScanner.setPHPMode(false);
127 fToken = TokenNameEOF;
131 while (fToken != TokenNameEOF && fToken != TokenNameERROR) {
132 if (fToken == TokenNamefunction) {
134 if (fToken == TokenNameAND) {
137 if (fToken == TokenNameIdentifier) {
138 ident = fScanner.getCurrentIdentifierSource();
142 parseDeclarations(buf, true);
144 } else if (fToken == TokenNameclass) {
146 if (fToken == TokenNameIdentifier) {
147 ident = fScanner.getCurrentIdentifierSource();
152 //skip fTokens for classname, extends and others until we have the opening '{'
153 while (fToken != TokenNameLBRACE && fToken != TokenNameEOF && fToken != TokenNameERROR) {
157 parseDeclarations(buf, true);
164 } catch (SyntaxError e) {
165 // TODO Auto-generated catch block
171 private HashMap fFileMap;
172 private String fFilename;
173 private HashMap fIndentifierMap;
175 public IdentifierIndexManager(String filename) {
176 fFilename = filename;
182 * Add the information for a given IFile resource
185 public void addFile(IFile fileToParse) {
187 LineCreator lineCreator = new LineCreator();
189 iStream = fileToParse.getContents();
191 StringBuffer buf = new StringBuffer();
194 while ((c0 = iStream.read()) != (-1)) {
195 buf.append((char) c0);
197 } catch (IOException e) {
201 StringBuffer lineBuffer = new StringBuffer();
202 // lineBuffer.append(fileToParse.getLocation().toString());
203 lineBuffer.append(fileToParse.getFullPath().toString());
204 int lineLength = lineBuffer.length();
205 lineCreator.parseIdentifiers(buf.toString().toCharArray(), lineBuffer);
206 if (lineLength != lineBuffer.length()) {
207 addLine(lineBuffer.toString());
209 } catch (CoreException e1) {
210 // TODO Auto-generated catch block
211 e1.printStackTrace();
216 * Adds a line of the index file for function, class, class-method and class-variable names
220 private void addLine(String line) {
221 StringTokenizer tokenizer;
222 String phpFileName = null;
224 String identifier = null;
225 String classname = null;
226 PHPIdentifier phpIdentifier = null;
227 boolean tokenExists = false;
229 tokenizer = new StringTokenizer(line, "\t");
230 // first token contains the filename:
231 if (tokenizer.hasMoreTokens()) {
232 phpFileName = tokenizer.nextToken();
233 //System.out.println(token);
237 // all the other tokens are identifiers:
238 while (tokenizer.hasMoreTokens()) {
239 token = tokenizer.nextToken();
240 //System.out.println(token);
241 switch (token.charAt(0)) {
242 case 'c' : // class name
243 identifier = token.substring(1);
244 classname = identifier;
245 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.CLASS, phpFileName);
247 case 'f' : // function name
248 identifier = token.substring(1);
249 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.FUNCTION, phpFileName);
251 case 'm' : //method inside a class
252 identifier = token.substring(1);
253 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.METHOD, phpFileName, classname);
255 case 'v' : // variable inside a class
256 identifier = token.substring(1);
257 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.VARIABLE, phpFileName, classname);
261 phpIdentifier = null;
264 if (identifier != null && phpIdentifier != null) {
266 ArrayList list = (ArrayList) fIndentifierMap.get(identifier);
268 list = new ArrayList();
269 list.add(phpIdentifier);
270 fIndentifierMap.put(identifier, list);
272 boolean flag = false;
273 for (int i = 0; i < list.size(); i++) {
274 if (list.get(i).equals(phpIdentifier)) {
280 list.add(phpIdentifier);
286 fFileMap.put(phpFileName, line);
291 * Change the information for a given IFile resource
294 public void changeFile(IFile fileToParse) {
295 removeFile(fileToParse);
296 addFile(fileToParse);
300 * Get a list of all PHPIdentifierLocation object's associated with an identifier
305 public List getLocations(String identifier) {
306 return (List) fIndentifierMap.get(identifier);
310 * Initialize (i.e. clear) the current index information
313 public void initialize() {
314 fIndentifierMap = new HashMap();
315 fFileMap = new HashMap();
318 private void readFile() {
320 FileReader fileReader;
322 fileReader = new FileReader(fFilename);
324 BufferedReader bufferedReader = new BufferedReader(fileReader);
327 while (bufferedReader.ready()) {
328 // all entries for one file are in a line
329 // separated by tabs !
330 line = bufferedReader.readLine();
335 } catch (FileNotFoundException e) {
337 // TODO DialogBox which asks the user if she/he likes to build new index?
338 } catch (IOException e) {
339 // TODO Auto-generated catch block
346 * Remove the information for a given IFile resource
349 public void removeFile(IFile fileToParse) {
350 // String line = (String) fFileMap.get(fileToParse.getLocation().toString());
351 String line = (String) fFileMap.get(fileToParse.getFullPath().toString());
358 * Removes a line of the index file for function, class, class-method and class-variable names
362 private void removeLine(String line) {
363 StringTokenizer tokenizer;
364 String phpFileName = null;
366 String identifier = null;
367 String classname = null;
368 PHPIdentifier phpIdentifier = null;
369 boolean tokenExists = false;
371 tokenizer = new StringTokenizer(line, "\t");
372 // first token contains the filename:
373 if (tokenizer.hasMoreTokens()) {
374 phpFileName = tokenizer.nextToken();
375 //System.out.println(token);
379 // all the other tokens are identifiers:
380 while (tokenizer.hasMoreTokens()) {
381 token = tokenizer.nextToken();
382 //System.out.println(token);
383 switch (token.charAt(0)) {
384 case 'c' : // class name
385 identifier = token.substring(1);
386 classname = identifier;
387 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.CLASS, phpFileName);
389 case 'f' : // function name
390 identifier = token.substring(1);
391 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.FUNCTION, phpFileName);
393 case 'm' : //method inside a class
394 identifier = token.substring(1);
395 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.METHOD, phpFileName, classname);
397 case 'v' : // variable inside a class
398 identifier = token.substring(1);
399 phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.VARIABLE, phpFileName, classname);
403 phpIdentifier = null;
406 if (identifier != null && phpIdentifier != null) {
407 ArrayList list = (ArrayList) fIndentifierMap.get(identifier);
410 for (int i = 0; i < list.size(); i++) {
411 if (list.get(i).equals(phpIdentifier)) {
416 if (list.size() == 0) {
417 fIndentifierMap.remove(identifier);
422 fFileMap.remove(phpFileName);
426 * Save the current index information in the projects index file
429 public void writeFile() {
430 FileWriter fileWriter;
432 fileWriter = new FileWriter(fFilename);
434 Collection collection = fFileMap.values();
435 Iterator iterator = collection.iterator();
436 while (iterator.hasNext()) {
437 line = (String) iterator.next();
438 fileWriter.write(line + '\n');
441 } catch (IOException e) {
442 // TODO Auto-generated catch block