Applied patch from scorphus for bug#1685307
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / actions / IncludesScanner.java
1 package net.sourceforge.phpeclipse.actions;
2
3 import java.io.BufferedInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.util.ArrayList;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Set;
10
11 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
12 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
13 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
14 import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
15 import net.sourceforge.phpdt.internal.compiler.util.Util;
16
17 import org.eclipse.core.resources.IContainer;
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.resources.IProject;
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.Path;
22 import org.eclipse.ui.IFileEditorInput;
23
24 public class IncludesScanner implements ITerminalSymbols {
25         // private final PHPOpenAllIncludesEditorAction fOpenAllIncludesAction;
26         private IProject fProject;
27
28         private IFileEditorInput fEditorInput;
29
30         private HashSet fSet;
31
32         public IncludesScanner(IProject project, IFileEditorInput editorInput) {
33                 fProject = project;
34                 // fOpenAllIncludesAction = action;
35                 fEditorInput = editorInput;
36                 fSet = new HashSet();
37         }
38
39         /**
40          * Add the information for a given IFile resource
41          * 
42          */
43         public void addFile(IFile fileToParse) {
44
45                 try {
46                         if (fileToParse.exists()) {
47                                 addInputStream(new BufferedInputStream(fileToParse
48                                                 .getContents()), fileToParse.getProjectRelativePath()
49                                                 .toString());
50                         }
51                 } catch (CoreException e1) {
52                         e1.printStackTrace();
53                 }
54         }
55
56         private void addInputStream(InputStream stream, String filePath)
57                         throws CoreException {
58                 try {
59                         if (fSet.add(filePath)) { // new entry in set
60                                 parseIdentifiers(Util.getInputStreamAsCharArray(stream, -1,
61                                                 null));
62                         }
63                 } catch (IOException e) {
64                         e.printStackTrace();
65                 } finally {
66                         try {
67                                 if (stream != null) {
68                                         stream.close();
69                                 }
70                         } catch (IOException e) {
71                         }
72                 }
73         }
74
75         /**
76          * Get the next token from input
77          */
78         private int getNextToken(Scanner scanner) {
79                 int token;
80                 try {
81                         token = scanner.getNextToken();
82                         if (Scanner.DEBUG) {
83                                 int currentEndPosition = scanner.getCurrentTokenEndPosition();
84                                 int currentStartPosition = scanner
85                                                 .getCurrentTokenStartPosition();
86                                 System.out.print(currentStartPosition + ","
87                                                 + currentEndPosition + ": ");
88                                 System.out.println(scanner.toStringAction(token));
89                         }
90                         return token;
91                 } catch (InvalidInputException e) {
92                 }
93                 return TokenNameERROR;
94         }
95
96         private void parseIdentifiers(char[] charArray) {
97                 char[] ident;
98                 IFile file;
99                 String identifier;
100                 int counter = 0;
101
102                 Scanner scanner = new Scanner(false, false, false, false, true, null,
103                                 null, true /* taskCaseSensitive */);
104                 scanner.setSource(charArray);
105                 scanner.setPHPMode(false);
106                 int token = getNextToken(scanner);
107                 try {
108                         while (token != TokenNameEOF) { // && fToken != TokenNameERROR) {
109                                 if (token == TokenNameinclude || token == TokenNameinclude_once
110                                                 || token == TokenNamerequire
111                                                 || token == TokenNamerequire_once) {
112                                         while (token != TokenNameEOF && token != TokenNameERROR
113                                                         && token != TokenNameSEMICOLON
114                                                         && token != TokenNameRPAREN
115                                                         && token != TokenNameLBRACE
116                                                         && token != TokenNameRBRACE) {
117                                                 token = getNextToken(scanner);
118                                                 if (token == TokenNameStringDoubleQuote
119                                                                 || token == TokenNameStringSingleQuote) {
120                                                         char[] includeName = scanner
121                                                                         .getCurrentStringLiteralSource();
122                                                         try {
123                                                                 file = getIncludeFile(new String(includeName));
124                                                                 addFile(file);
125                                                         } catch (Exception e) {
126                                                                 // ignore
127                                                         }
128                                                         break;
129                                                 }
130                                         }
131                                 }
132                                 token = getNextToken(scanner);
133                         }
134                 } catch (SyntaxError e) {
135                         // e.printStackTrace();
136                 }
137         }
138
139         private IContainer getWorkingLocation(IFileEditorInput editorInput) {
140                 if (editorInput == null || editorInput.getFile() == null) {
141                         return null;
142                 }
143                 return editorInput.getFile().getParent();
144         }
145
146         public IFile getIncludeFile(String relativeFilename) {
147                 IContainer container = getWorkingLocation(fEditorInput);
148                 String fullPath = fProject.getLocation().toString();
149                 IFile file = null;
150                 if (relativeFilename.startsWith("../")) {
151                         Path path = new Path(relativeFilename);
152                         file = container.getFile(path);
153                         return file;
154                 }
155                 int index = relativeFilename.lastIndexOf('/');
156
157                 if (index >= 0) {
158                         Path path = new Path(relativeFilename);
159                         file = fProject.getFile(path);
160                         if (file.exists()) {
161                                 return file;
162                         }
163                 }
164                 Path path = new Path(relativeFilename);
165                 file = container.getFile(path);
166
167                 return file;
168         }
169
170         /**
171          * Returns a list of includes
172          * 
173          * @return the determined list of includes
174          */
175         public List getList() {
176                 ArrayList list = new ArrayList();
177                 list.addAll(fSet);
178                 return list;
179         }
180
181         /**
182          * @return Returns the set.
183          */
184         public Set getSet() {
185                 return fSet;
186         }
187 }