improved PHP parser
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / text / template / DeclarationEngine.java
1 /*
2  * (c) Copyright IBM Corp. 2000, 2001.
3  * All Rights Reserved.
4  */
5 package net.sourceforge.phpdt.internal.ui.text.template;
6
7 import java.util.ArrayList;
8 import java.util.Iterator;
9 import java.util.SortedMap;
10
11 import net.sourceforge.phpdt.core.ICompilationUnit;
12 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
13 import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitContextType;
14 import net.sourceforge.phpdt.internal.corext.template.php.JavaContext;
15 import net.sourceforge.phpdt.internal.corext.template.php.JavaContextType;
16 import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
17 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
18 import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
19
20 import org.eclipse.core.resources.IFile;
21 import org.eclipse.core.resources.IProject;
22 import org.eclipse.jface.text.BadLocationException;
23 import org.eclipse.jface.text.IDocument;
24 import org.eclipse.jface.text.IRegion;
25 import org.eclipse.jface.text.ITextViewer;
26 import org.eclipse.jface.text.Region;
27 import org.eclipse.swt.graphics.Point;
28 //import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
29
30 public class DeclarationEngine {
31
32   /** The context type. */
33   private JavaContextType fContextType;
34   /** The result proposals. */
35   private ArrayList fProposals = new ArrayList();
36   /** Token determines last which declarations are allowed for proposal */
37   private int fLastSignificantToken;
38
39   private IProject fProject;
40 //  private IFile fFile;
41   private String fFileName;
42
43   /**
44    * Creates the template engine for a particular context type.
45    * See <code>TemplateContext</code> for supported context types.
46    */
47   public DeclarationEngine(IProject project, JavaContextType contextType, int lastSignificantToken, IFile file) {
48     //  Assert.isNotNull(contextType);
49     fProject = project;
50     fContextType = contextType;
51
52     fLastSignificantToken = lastSignificantToken;
53 //    fFile = file;
54     if (file != null) {
55       fFileName = file.getProjectRelativePath().toString();
56     } else {
57       fFileName = "";
58     }
59   }
60
61   /**
62    * Empties the collector.
63    * 
64    * @param viewer the text viewer  
65    * @param unit   the compilation unit (may be <code>null</code>)
66    */
67   public void reset() {
68     fProposals.clear();
69   }
70
71   /**
72    * Returns the array of matching templates.
73    */
74   public IPHPCompletionProposal[] getResults() {
75     return (IPHPCompletionProposal[]) fProposals.toArray(new IPHPCompletionProposal[fProposals.size()]);
76   }
77
78   /**
79    * Inspects the context of the compilation unit around <code>completionPosition</code>
80    * and feeds the collector with proposals.
81    * 
82    * @param viewer the text viewer
83    * @param completionPosition the context position in the document of the text viewer
84    * @param compilationUnit the compilation unit (may be <code>null</code>)
85    */
86   public void completeObject(ITextViewer viewer, int completionPosition, SortedMap map, ICompilationUnit compilationUnit) {
87     IDocument document = viewer.getDocument();
88
89     if (!(fContextType instanceof CompilationUnitContextType))
90       return;
91
92     Point selection = viewer.getSelectedRange();
93
94     // remember selected text
95     String selectedText = null;
96
97     if (selection.y != 0) {
98       try {
99         selectedText = document.get(selection.x, selection.y);
100       } catch (BadLocationException e) {
101       }
102     }
103
104     JavaContext context = (JavaContext) fContextType.createContext(document, completionPosition,selection.y,compilationUnit);
105     context.setVariable("selection", selectedText); //$NON-NLS-1$
106
107     int start = context.getStart();
108     int end = context.getEnd();
109     String prefix = context.getKey();
110     IRegion region = new Region(start, end - start);
111
112     String identifier = null;
113
114     SortedMap subMap = map.subMap(prefix, prefix + '\255');
115     Iterator iter = subMap.keySet().iterator();
116     PHPIdentifierLocation location;
117     ArrayList list; 
118     int maxProposals = PHPeclipsePlugin.MAX_PROPOSALS;
119     while (iter.hasNext()) {
120       identifier = (String) iter.next();
121       if (context.canEvaluate(identifier)) {
122         list = (ArrayList) subMap.get(identifier);
123         for (int i = 0; i < list.size(); i++) {
124           location = (PHPIdentifierLocation) list.get(i);
125           int type = location.getType();
126           switch (fLastSignificantToken) {
127             case ITerminalSymbols.TokenNameMINUS_GREATER :
128               if (type != PHPIdentifierLocation.METHOD && type != PHPIdentifierLocation.VARIABLE) {
129                 continue; // for loop
130               }
131               break;
132             case ITerminalSymbols.TokenNameVariable :
133               if (type != PHPIdentifierLocation.METHOD && type != PHPIdentifierLocation.VARIABLE) {
134                 continue; // for loop
135               }
136 //            check all filenames of the subclasses
137 //              if (fFileName.equals(location.getFilename())) {
138 //                continue; // for loop
139 //              }
140               break;
141             case ITerminalSymbols.TokenNamethis_PHP_COMPLETION:
142               if (type != PHPIdentifierLocation.METHOD && type != PHPIdentifierLocation.VARIABLE) {
143                 continue; // for loop
144               }
145               // check all filenames of the subclasses
146 //              if (!fFileName.equals(location.getFilename())) {
147 //                continue; // for loop
148 //              }
149               break;
150             case ITerminalSymbols.TokenNamenew :
151               if (type != PHPIdentifierLocation.CLASS && type != PHPIdentifierLocation.CONSTRUCTOR) {
152                 continue; // for loop
153               }
154               break;
155             default :
156               if (type == PHPIdentifierLocation.METHOD || type == PHPIdentifierLocation.CONSTRUCTOR || type == PHPIdentifierLocation.VARIABLE) {
157                 continue; // for loop
158               }
159           }
160           if (maxProposals-- < 0) {
161             return;
162           }
163           fProposals.add( new DeclarationProposal(fProject, identifier, location, context, region, viewer));
164         }
165       }
166     }
167
168   }
169   
170   /**
171    * Inspects the context of the compilation unit around <code>completionPosition</code>
172    * and feeds the collector with proposals.
173    * @param viewer the text viewer
174    * @param completionPosition the context position in the document of the text viewer
175    * @param compilationUnit the compilation unit (may be <code>null</code>)
176    */
177   public void complete(ITextViewer viewer, int completionPosition, SortedMap map, ICompilationUnit compilationUnit) {
178     IDocument document = viewer.getDocument();
179
180     if (!(fContextType instanceof CompilationUnitContextType))
181       return;
182
183     Point selection = viewer.getSelectedRange();
184
185     // remember selected text
186     String selectedText = null;
187
188     if (selection.y != 0) {
189       try {
190         selectedText = document.get(selection.x, selection.y);
191       } catch (BadLocationException e) {
192       }
193     }
194
195 //    ((CompilationUnitContextType) fContextType).setContextParameters(document, completionPosition, selection.y);
196
197 //    CompilationUnitContext context = (CompilationUnitContext) fContextType.createContext();
198     JavaContext context = (JavaContext) fContextType.createContext(document, completionPosition,selection.y,compilationUnit);
199     context.setVariable("selection", selectedText); //$NON-NLS-1$
200
201     int start = context.getStart();
202     int end = context.getEnd();
203     String prefix = context.getKey();
204     IRegion region = new Region(start, end - start);
205
206     String identifier = null;
207
208     SortedMap subMap = map.subMap(prefix, prefix + '\255');
209     Iterator iter = subMap.keySet().iterator();
210     PHPIdentifierLocation location;
211     ArrayList list;
212     int maxProposals = PHPeclipsePlugin.MAX_PROPOSALS;
213     while (iter.hasNext()) {
214       identifier = (String) iter.next();
215       if (context.canEvaluate(identifier)) {
216         list = (ArrayList) subMap.get(identifier);
217         for (int i = 0; i < list.size(); i++) {
218           location = (PHPIdentifierLocation) list.get(i);
219           int type = location.getType();
220           switch (fLastSignificantToken) {
221             case ITerminalSymbols.TokenNameMINUS_GREATER :
222               if (type != PHPIdentifierLocation.METHOD && type != PHPIdentifierLocation.VARIABLE) {
223                 continue; // for loop
224               }
225               break;
226             case ITerminalSymbols.TokenNameVariable :
227               if (type != PHPIdentifierLocation.METHOD && type != PHPIdentifierLocation.VARIABLE) {
228                 continue; // for loop
229               }
230 //            check all filenames of the subclasses
231               if (fFileName.equals(location.getFilename())) {
232                 continue; // for loop
233               }
234               break;
235             case ITerminalSymbols.TokenNamethis_PHP_COMPLETION:
236               if (type != PHPIdentifierLocation.METHOD && type != PHPIdentifierLocation.VARIABLE) {
237                 continue; // for loop
238               }
239               // check all filenames of the subclasses
240               if (!fFileName.equals(location.getFilename())) {
241                 continue; // for loop
242               }
243               break;
244             case ITerminalSymbols.TokenNamenew :
245               if (type != PHPIdentifierLocation.CLASS && type != PHPIdentifierLocation.CONSTRUCTOR) {
246                 continue; // for loop
247               }
248               break;
249             default :
250               if (type == PHPIdentifierLocation.METHOD || type == PHPIdentifierLocation.CONSTRUCTOR || type == PHPIdentifierLocation.VARIABLE) {
251                 continue; // for loop
252               }
253           }
254           if (maxProposals-- < 0) {
255             return;
256           }
257           fProposals.add( new DeclarationProposal(fProject, identifier, location, context, region, viewer));
258         }
259       }
260     }
261
262   }
263
264 }