fix #774 infinite loop in net.sourceforge.phpeclipse.builder.IdentifierIndexManager...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / obfuscator / ObfuscatorPass1Exporter.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpeclipse.obfuscator;
12
13 import java.io.BufferedInputStream;
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.util.ArrayList;
17 import java.util.HashMap;
18
19 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
20 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
21 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
22 import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
23 import net.sourceforge.phpdt.internal.compiler.util.Util;
24 import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
25 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
26
27 import org.eclipse.core.resources.IContainer;
28 import org.eclipse.core.resources.IFile;
29 import org.eclipse.core.resources.IResource;
30 import org.eclipse.core.runtime.CoreException;
31 import org.eclipse.core.runtime.IPath;
32 import org.eclipse.jface.preference.IPreferenceStore;
33
34 /**
35  * Analyzing php files in a first pass over all resources !
36  */
37 public class ObfuscatorPass1Exporter implements ITerminalSymbols {
38
39         protected Scanner fScanner;
40
41         protected int fToken;
42
43         protected HashMap fIdentifierMap;
44
45         public ObfuscatorPass1Exporter(Scanner scanner, HashMap identifierMap) {
46                 fScanner = scanner;
47                 fIdentifierMap = identifierMap;
48         }
49
50         /**
51          * Get the next token from input
52          */
53         private void getNextToken() {
54
55                 try {
56                         fToken = fScanner.getNextToken();
57                         if (Scanner.DEBUG) {
58                                 int currentEndPosition = fScanner.getCurrentTokenEndPosition();
59                                 int currentStartPosition = fScanner
60                                                 .getCurrentTokenStartPosition();
61
62                                 System.out.print(currentStartPosition + ","
63                                                 + currentEndPosition + ": ");
64                                 System.out.println(fScanner.toStringAction(fToken));
65                         }
66                         return;
67                 } catch (InvalidInputException e) {
68
69                 }
70                 fToken = TokenNameERROR;
71         }
72
73         private void parseIdentifiers(boolean goBack) {
74                 char[] ident;
75                 String identifier;
76                 PHPIdentifier value;
77                 int counter = 0;
78
79                 IPreferenceStore store = PHPeclipsePlugin.getDefault()
80                                 .getPreferenceStore();
81                 try {
82                         while (fToken != TokenNameEOF && fToken != TokenNameERROR) {
83                                 if (fToken == TokenNameVariable) {
84                                         identifier = new String(fScanner
85                                                         .getCurrentIdentifierSource());
86                                         value = (PHPIdentifier) fIdentifierMap.get(identifier);
87                                         if (value == null) {
88                                                 fIdentifierMap.put(identifier, new PHPIdentifier(null,
89                                                                 PHPIdentifier.VARIABLE));
90                                         }
91                                         getNextToken();
92                                         // } else if (fToken == TokenNamefunction) {
93                                         // getNextToken();
94                                         // if (fToken == TokenNameAND) {
95                                         // getNextToken();
96                                         // }
97                                         // if (fToken == TokenNameIdentifier) {
98                                         // ident = fScanner.getCurrentIdentifierSource();
99                                         // outlineInfo.addVariable(new String(ident));
100                                         // temp = new PHPFunctionDeclaration(current, new
101                                         // String(ident), fScanner.getCurrentTokenStartPosition());
102                                         // current.add(temp);
103                                         // getNextToken();
104                                         // parseDeclarations(outlineInfo, temp, true);
105                                         // }
106                                         // } else if (fToken == TokenNameclass) {
107                                         // getNextToken();
108                                         // if (fToken == TokenNameIdentifier) {
109                                         // ident = fScanner.getCurrentIdentifierSource();
110                                         // outlineInfo.addVariable(new String(ident));
111                                         // temp = new PHPClassDeclaration(current, new
112                                         // String(ident), fScanner.getCurrentTokenStartPosition());
113                                         // current.add(temp);
114                                         // getNextToken();
115                                         //
116                                         // //skip fTokens for classname, extends and others until we
117                                         // have the opening '{'
118                                         // while (fToken != TokenNameLBRACE && fToken !=
119                                         // TokenNameEOF && fToken != TokenNameERROR) {
120                                         // getNextToken();
121                                         // }
122                                         // parseDeclarations(outlineInfo, temp, true);
123                                         // // stack.pop();
124                                         // }
125                                 } else if (fToken == TokenNameStringDoubleQuote) {
126                                         char currentCharacter;
127                                         int i = fScanner.startPosition;
128                                         ArrayList varList = new ArrayList();
129
130                                         while (i < fScanner.currentPosition) {
131                                                 currentCharacter = fScanner.source[i++];
132                                                 if (currentCharacter == '$'
133                                                                 && fScanner.source[i - 2] != '\\') {
134                                                         StringBuffer varName = new StringBuffer();
135                                                         varName.append("$");
136                                                         while (i < fScanner.currentPosition) {
137                                                                 currentCharacter = fScanner.source[i++];
138                                                                 if (!Scanner
139                                                                                 .isPHPIdentifierPart(currentCharacter)) {
140                                                                         break; // while loop
141                                                                 }
142                                                                 varName.append(currentCharacter);
143                                                         }
144                                                         varList.add(varName.toString());
145                                                 }
146                                         }
147
148                                         for (i = 0; i < varList.size(); i++) {
149                                                 identifier = (String) varList.get(i);
150                                                 value = (PHPIdentifier) fIdentifierMap.get(identifier);
151                                                 if (value == null) {
152                                                         fIdentifierMap.put(identifier, new PHPIdentifier(
153                                                                         null, PHPIdentifier.VARIABLE));
154                                                 }
155                                         }
156
157                                         getNextToken();
158                                 } else if (fToken == TokenNameLBRACE) {
159                                         getNextToken();
160                                         counter++;
161                                 } else if (fToken == TokenNameRBRACE) {
162                                         getNextToken();
163                                         --counter;
164                                         if (counter == 0 && goBack) {
165                                                 return;
166                                         }
167                                 } else {
168                                         getNextToken();
169                                 }
170                         }
171                 } catch (SyntaxError sytaxErr) {
172                         // do nothing
173                 }
174         }
175
176         /**
177          * Do nothing in first pass
178          */
179         public void createFolder(IPath destinationPath) {
180                 // do nothing here
181                 // new File(destinationPath.toOSString()).mkdir();
182         }
183
184         /**
185          * Writes the passed resource to the specified location recursively
186          */
187         public void write(IResource resource, IPath destinationPath)
188                         throws CoreException, IOException {
189                 if (resource.getType() == IResource.FILE)
190                         writeFile((IFile) resource, destinationPath);
191                 else
192                         writeChildren((IContainer) resource, destinationPath);
193         }
194
195         /**
196          * Exports the passed container's children
197          */
198         protected void writeChildren(IContainer folder, IPath destinationPath)
199                         throws CoreException, IOException {
200                 if (folder.isAccessible()) {
201                         IResource[] children = folder.members();
202                         for (int i = 0; i < children.length; i++) {
203                                 IResource child = children[i];
204                                 writeResource(child, destinationPath.append(child.getName()));
205                         }
206                 }
207         }
208
209         /**
210          * Analyzes the passed file resource for the PHP obfuscator
211          */
212         protected void writeFile(IFile file, IPath destinationPath)
213                         throws IOException, CoreException {
214                 if (!PHPFileUtil.isPHPFile(file)) {
215                         return;
216                 }
217                 InputStream stream = null;
218                 char[] charArray = null;
219                 try {
220                         stream = new BufferedInputStream(file.getContents());
221                         charArray = Util.getInputStreamAsCharArray(stream, -1, null);
222                 } catch (IOException e) {
223                         return;
224                 } finally {
225                         try {
226                                 if (stream != null) {
227                                         stream.close();
228                                 }
229                         } catch (IOException e) {
230                         }
231                 }
232
233                 if (charArray == null) {
234                         // TODO show error message
235                         return;
236                 }
237                 /* fScanner initialization */
238                 fScanner.setSource(charArray);
239                 fScanner.setPHPMode(false);
240                 fToken = TokenNameEOF;
241                 getNextToken();
242                 parseIdentifiers(false);
243         }
244
245         /**
246          * Writes the passed resource to the specified location recursively
247          */
248         protected void writeResource(IResource resource, IPath destinationPath)
249                         throws CoreException, IOException {
250                 if (resource.getType() == IResource.FILE)
251                         writeFile((IFile) resource, destinationPath);
252                 else {
253                         createFolder(destinationPath);
254                         writeChildren((IContainer) resource, destinationPath);
255                 }
256         }
257 }