Changes:
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / corext / template / php / CompilationUnitCompletion.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.phpdt.internal.corext.template.php;
12
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Vector;
19
20 import net.sourceforge.phpdt.core.CompletionRequestorAdapter;
21 import net.sourceforge.phpdt.core.ICompilationUnit;
22 import net.sourceforge.phpdt.core.JavaModelException;
23 import net.sourceforge.phpdt.core.compiler.IProblem;
24
25
26
27 /**
28  * A completion requestor to collect informations on local variables.
29  * This class is used for guessing variable names like arrays, collections, etc.
30  */
31 class CompilationUnitCompletion extends CompletionRequestorAdapter {
32
33         static class LocalVariable {
34                 String name;
35                 String typePackageName;
36                 String typeName;
37                 
38                 LocalVariable(String name, String typePackageName, String typeName) {
39                         this.name= name;
40                         this.typePackageName= typePackageName;
41                         this.typeName= typeName;
42                 }
43         }
44
45         private ICompilationUnit fUnit;
46
47         private List fLocalVariables= new ArrayList();
48         private Map fTypes= new HashMap();
49
50
51         private boolean fError;
52
53         /**
54          * Creates a compilation unit completion.
55          * 
56          * @param unit the compilation unit, may be <code>null</code>.
57          */
58         public CompilationUnitCompletion(ICompilationUnit unit) {
59                 reset(unit);
60         }
61         
62         /**
63          * Resets the completion requestor.
64          * 
65          * @param unit the compilation unit, may be <code>null</code>.
66          */
67         public void reset(ICompilationUnit unit) {
68                 fUnit= unit;
69                 
70                 fLocalVariables.clear();
71                 fTypes.clear();
72                 
73                 fError= false;
74         }
75
76         /*
77          * @see ICompletionRequestor#acceptError(IProblem)
78          */
79         public void acceptError(IProblem error) {
80                 fError= true;
81         }
82
83
84         /*
85          * @see ICodeCompletionRequestor#acceptLocalVariable
86          */
87         public void acceptLocalVariable(char[] name, char[] typePackageName, char[] typeName,
88                 int modifiers, int completionStart,     int completionEnd, int relevance)
89         {
90                 fLocalVariables.add(new LocalVariable(
91                         new String(name), new String(typePackageName), new String(typeName)));
92         }
93
94
95         // ---
96
97         /**
98          * Tests if the code completion process produced errors.
99          */
100         public boolean hasErrors() {
101                 return fError;
102         }
103         
104
105         boolean existsLocalName(String name) {
106                 for (Iterator iterator = fLocalVariables.iterator(); iterator.hasNext();) {
107                         LocalVariable localVariable = (LocalVariable) iterator.next();
108
109                         if (localVariable.name.equals(name))
110                                 return true;
111                 }
112
113                 return false;
114         }
115         
116         String[] getLocalVariableNames() {
117                 String[] res= new String[fLocalVariables.size()];
118                 int i= 0;
119                 for (Iterator iterator = fLocalVariables.iterator(); iterator.hasNext();) {
120                         LocalVariable localVariable = (LocalVariable) iterator.next();
121                         res[i++]= localVariable.name;
122                 }               
123                 return res;
124         }       
125
126         LocalVariable[] findLocalArrays() {
127                 Vector vector= new Vector();
128
129                 for (Iterator iterator= fLocalVariables.iterator(); iterator.hasNext();) {
130                         LocalVariable localVariable= (LocalVariable) iterator.next();
131
132                         if (isArray(localVariable.typeName))
133                                 vector.add(localVariable);
134                 }
135
136                 return (LocalVariable[]) vector.toArray(new LocalVariable[vector.size()]);
137         }
138         
139         LocalVariable[] findLocalCollections() throws JavaModelException {
140                 Vector vector= new Vector();
141
142                 for (Iterator iterator= fLocalVariables.iterator(); iterator.hasNext();) {
143                         LocalVariable localVariable= (LocalVariable) iterator.next();
144
145                         String typeName= qualify(localVariable.typeName);
146                         
147                         if (typeName == null)
148                                 continue;
149                                                 
150                         if (isSubclassOf(typeName, "java.util.Collection")) //$NON-NLS-1$                       
151                                 vector.add(localVariable);
152                 }
153
154                 return (LocalVariable[]) vector.toArray(new LocalVariable[vector.size()]);
155         }
156
157         String simplifyTypeName(String qualifiedName) {
158                 return (String) fTypes.get(qualifiedName);      
159         }
160
161         private LocalVariable[] findLocalIntegers() {
162                 Vector vector= new Vector();
163
164                 for (Iterator iterator= fLocalVariables.iterator(); iterator.hasNext();) {
165                         LocalVariable localVariable= (LocalVariable) iterator.next();
166
167                         if (localVariable.typeName.equals("int")) //$NON-NLS-1$
168                                 vector.add(localVariable);
169                 }
170
171                 return (LocalVariable[]) vector.toArray(new LocalVariable[vector.size()]);
172         }
173
174         private LocalVariable[] findLocalIterator() throws JavaModelException {
175                 Vector vector= new Vector();
176
177                 for (Iterator iterator= fLocalVariables.iterator(); iterator.hasNext();) {
178                         LocalVariable localVariable= (LocalVariable) iterator.next();
179
180                         String typeName= qualify(localVariable.typeName);                       
181
182                         if (typeName == null)
183                                 continue;
184
185                         if (isSubclassOf(typeName, "java.util.Iterator")) //$NON-NLS-1$
186                                 vector.add(localVariable);
187                 }
188
189                 return (LocalVariable[]) vector.toArray(new LocalVariable[vector.size()]);
190         }       
191
192         private static boolean isArray(String type) {
193                 return type.endsWith("[]"); //$NON-NLS-1$
194         }
195         
196         // returns fully qualified name if successful
197         private String qualify(String typeName) throws JavaModelException {
198                 if (fUnit == null)
199                         return null;
200
201 //              IType[] types= fUnit.getTypes();
202 //
203 //              if (types.length == 0)
204 //                      return null;
205 //              
206 //              String[][] resolvedTypeNames= types[0].resolveType(typeName);
207 //
208 //              if (resolvedTypeNames == null)
209 //                      return null;
210 //                      
211 //              return resolvedTypeNames[0][0] + '.' + resolvedTypeNames[0][1];
212     return null;
213         }       
214         
215         // type names must be fully qualified
216         private boolean isSubclassOf(String typeName0, String typeName1) throws JavaModelException {
217                 if (typeName0.equals(typeName1))
218                         return true;
219
220                 if (fUnit == null)
221                         return false;
222
223 //              IJavaProject project= fUnit.getJavaProject();
224 //              IType type0= project.findType(typeName0);
225 //              IType type1= project.findType(typeName1);
226 //
227 //              ITypeHierarchy hierarchy= type0.newSupertypeHierarchy(null);
228 //              IType[] superTypes= hierarchy.getAllSupertypes(type0);
229 //              
230 //              for (int i= 0; i < superTypes.length; i++)
231 //                      if (superTypes[i].equals(type1))
232 //                              return true;                    
233                 
234                 return false;
235         }
236
237         /*
238          * @see org.eclipse.jdt.core.ICompletionRequestor#acceptClass(char[], char[], char[], int, int, int, int)
239          */
240         public void acceptClass(char[] packageName, char[] className, char[] completionName, int modifiers,
241                 int completionStart, int completionEnd, int relevance)
242         {
243                 final String qualifiedName= createQualifiedTypeName(packageName, className);
244                 fTypes.put(qualifiedName, String.valueOf(completionName));
245         }
246
247         /*
248          * @see org.eclipse.jdt.core.ICompletionRequestor#acceptInterface(char[], char[], char[], int, int, int, int)
249          */
250         public void acceptInterface(char[] packageName, char[] interfaceName, char[] completionName,
251                 int modifiers, int completionStart, int completionEnd, int relevance)
252         {
253                 final String qualifiedName= createQualifiedTypeName(packageName, interfaceName);
254                 fTypes.put(qualifiedName, String.valueOf(completionName));
255         }
256
257         private static String createQualifiedTypeName(char[] packageName, char[] className) {
258                 StringBuffer buffer= new StringBuffer();
259
260                 if (packageName.length != 0) {
261                         buffer.append(packageName);
262                         buffer.append('.');
263                 }
264                 buffer.append(className);
265                 
266                 return buffer.toString();
267         }
268
269 }
270