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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.corext.template.php;
13 import java.lang.reflect.InvocationTargetException;
15 import net.sourceforge.phpdt.core.ICompilationUnit;
16 import net.sourceforge.phpdt.core.JavaModelException;
17 import net.sourceforge.phpdt.internal.corext.Assert;
18 import net.sourceforge.phpdt.internal.corext.template.ContextType;
19 import net.sourceforge.phpdt.internal.corext.template.ContextTypeRegistry;
20 import net.sourceforge.phpdt.internal.corext.template.Template;
21 import net.sourceforge.phpdt.internal.corext.template.TemplateBuffer;
22 import net.sourceforge.phpdt.internal.corext.template.TemplateTranslator;
23 import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitCompletion.LocalVariable;
24 import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
25 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
27 import org.eclipse.core.runtime.CoreException;
28 import org.eclipse.core.runtime.IStatus;
29 import org.eclipse.core.runtime.Status;
30 import org.eclipse.jface.dialogs.MessageDialog;
31 import org.eclipse.jface.preference.IPreferenceStore;
32 import org.eclipse.jface.text.BadLocationException;
33 import org.eclipse.jface.text.Document;
34 import org.eclipse.jface.text.IDocument;
35 import org.eclipse.swt.widgets.Shell;
38 * A context for java source.
40 public class JavaContext extends PHPUnitContext {
42 /** The platform default line delimiter. */
43 private static final String PLATFORM_LINE_DELIMITER= System.getProperty("line.separator"); //$NON-NLS-1$
45 /** A code completion requestor for guessing local variable names. */
46 private CompilationUnitCompletion fCompletion;
49 * Creates a java template context.
51 * @param type the context type.
52 * @param document the document.
53 * @param completionOffset the completion offset within the document.
54 * @param completionLength the completion length.
55 * @param unit the compilation unit (may be <code>null</code>).
57 public JavaContext(ContextType type, IDocument document, int completionOffset, int completionLength,
58 ICompilationUnit compilationUnit)
60 super(type, document, completionOffset, completionLength); //, compilationUnit);
64 * Returns the indentation level at the position of code completion.
66 private int getIndentation() {
67 // int start= getStart();
68 // IDocument document= getDocument();
70 // IRegion region= document.getLineInformationOfOffset(start);
71 // String lineContent= document.get(region.getOffset(), region.getLength());
72 // return Strings.computeIndent(lineContent, CodeFormatterUtil.getTabWidth());
73 // } catch (BadLocationException e) {
80 * @see TemplateContext#evaluate(Template template)
82 public TemplateBuffer evaluate(Template template) throws CoreException {
84 if (!canEvaluate(template))
87 TemplateTranslator translator= new TemplateTranslator();
88 TemplateBuffer buffer= translator.translate(template.getPattern());
90 getContextType().edit(buffer, this);
92 String lineDelimiter= null;
94 lineDelimiter= getDocument().getLineDelimiter(0);
95 } catch (BadLocationException e) {
98 if (lineDelimiter == null)
99 lineDelimiter= PLATFORM_LINE_DELIMITER;
101 IPreferenceStore prefs= PHPeclipsePlugin.getDefault().getPreferenceStore();
102 // boolean useCodeFormatter= prefs.getBoolean(PreferenceConstants.TEMPLATES_USE_CODEFORMATTER);
104 // ITemplateEditor formatter= new JavaFormatter(lineDelimiter, getIndentation(), useCodeFormatter);
105 // formatter.edit(buffer, this);
111 * @see TemplateContext#canEvaluate(Template templates)
113 public boolean canEvaluate(Template template) {
114 String key= getKey();
116 if (fForceEvaluation)
120 template.matches(key, getContextType().getName()) &&
121 key.length() != 0 && template.getName().toLowerCase().startsWith(key.toLowerCase());
125 * @see DocumentTemplateContext#getCompletionPosition();
127 public int getStart() {
130 IDocument document= getDocument();
132 if (getCompletionLength() == 0) {
134 int start= getCompletionOffset();
135 while ((start != 0) && Character.isUnicodeIdentifierPart(document.getChar(start - 1)))
138 if ((start != 0) && Character.isUnicodeIdentifierStart(document.getChar(start - 1)))
145 int start= getCompletionOffset();
146 int end= getCompletionOffset() + getCompletionLength();
148 while (start != 0 && Character.isUnicodeIdentifierPart(document.getChar(start - 1)))
151 while (start != end && Character.isWhitespace(document.getChar(start)))
155 start= getCompletionOffset();
160 } catch (BadLocationException e) {
161 return super.getStart();
166 * @see org.eclipse.jdt.internal.corext.template.DocumentTemplateContext#getEnd()
168 public int getEnd() {
170 if (getCompletionLength() == 0)
171 return super.getEnd();
174 IDocument document= getDocument();
176 int start= getCompletionOffset();
177 int end= getCompletionOffset() + getCompletionLength();
179 while (start != end && Character.isWhitespace(document.getChar(end - 1)))
184 } catch (BadLocationException e) {
185 return super.getEnd();
190 * @see org.eclipse.jdt.internal.corext.template.DocumentTemplateContext#getKey()
192 public String getKey() {
194 if (getCompletionLength() == 0)
195 return super.getKey();
198 IDocument document= getDocument();
200 int start= getStart();
201 int end= getCompletionOffset();
203 ? document.get(start, end - start)
206 } catch (BadLocationException e) {
207 return super.getKey();
212 * Returns the character before start position of completion.
214 public char getCharacterBeforeStart() {
215 int start= getStart();
220 : getDocument().getChar(start - 1);
222 } catch (BadLocationException e) {
227 private CompilationUnitCompletion guessVariableNames() {
228 // ICompilationUnit unit= getCompilationUnit();
229 // int start= getStart();
235 // CompilationUnitCompletion collector= new CompilationUnitCompletion(unit);
236 // unit.codeComplete(start, collector);
239 // } catch (JavaModelException e) {
240 // handleException(null, e);
247 private static void handleException(Shell shell, Exception e) {
248 String title= PHPTemplateMessages.getString("JavaContext.error.title"); //$NON-NLS-1$
249 if (e instanceof CoreException)
250 ExceptionHandler.handle((CoreException)e, shell, title, null);
251 else if (e instanceof InvocationTargetException)
252 ExceptionHandler.handle((InvocationTargetException)e, shell, title, null);
254 PHPeclipsePlugin.log(e);
255 MessageDialog.openError(shell, title, e.getMessage());
259 private CompilationUnitCompletion getCompletion() {
260 // ICompilationUnit compilationUnit= getCompilationUnit();
261 // if (fCompletion == null) {
262 // fCompletion= new CompilationUnitCompletion(compilationUnit);
264 // if (compilationUnit != null) {
266 // compilationUnit.codeComplete(getStart(), fCompletion);
267 // } catch (JavaModelException e) {
273 // return fCompletion;
278 * Returns the name of a guessed local array, <code>null</code> if no local
281 public String guessArray() {
282 CompilationUnitCompletion completion= getCompletion();
283 LocalVariable[] localArrays= completion.findLocalArrays();
285 if (localArrays.length > 0)
286 return localArrays[localArrays.length - 1].name;
292 * Returns the name of the type of a local array, <code>null</code> if no local
295 public String guessArrayType() {
296 CompilationUnitCompletion completion= getCompletion();
297 LocalVariable[] localArrays= completion.findLocalArrays();
299 if (localArrays.length > 0) {
300 LocalVariable localArray= localArrays[localArrays.length - 1];
302 String arrayTypeName= localArray.typeName;
303 String typeName= getScalarType(arrayTypeName);
304 int dimension= getArrayDimension(arrayTypeName) - 1;
305 Assert.isTrue(dimension >= 0);
307 String qualifiedName= createQualifiedTypeName(localArray.typePackageName, typeName);
308 String innerTypeName= completion.simplifyTypeName(qualifiedName);
310 return innerTypeName == null
311 ? createArray(typeName, dimension)
312 : createArray(innerTypeName, dimension);
318 private static String createArray(String type, int dimension) {
319 StringBuffer buffer= new StringBuffer(type);
320 for (int i= 0; i < dimension; i++)
321 buffer.append("[]"); //$NON-NLS-1$
322 return buffer.toString();
325 private static String getScalarType(String type) {
326 return type.substring(0, type.indexOf('['));
329 private static int getArrayDimension(String type) {
332 int index= type.indexOf('[');
334 while (index != -1) {
336 index= type.indexOf('[', index + 1);
342 private static String createQualifiedTypeName(String packageName, String className) {
343 StringBuffer buffer= new StringBuffer();
345 if (packageName.length() != 0) {
346 buffer.append(packageName);
349 buffer.append(className);
351 return buffer.toString();
355 * Returns a proposal for a variable name of a local array element, <code>null</code>
356 * if no local array exists.
358 public String guessArrayElement() {
359 // CompilationUnitCompletion completion= getCompletion();
360 // LocalVariable[] localArrays= completion.findLocalArrays();
362 // if (localArrays.length > 0) {
363 // int idx= localArrays.length - 1;
365 // LocalVariable var= localArrays[idx];
367 // IJavaProject project= getCompilationUnit().getJavaProject();
368 // String typeName= var.typeName;
369 // String baseTypeName= typeName.substring(0, typeName.lastIndexOf('['));
371 // String[] proposals= NamingConventions.suggestLocalVariableNames(project, var.typePackageName, baseTypeName, 0, completion.getLocalVariableNames());
372 // if (proposals.length > 0) {
373 // return proposals[0];
381 * Returns an array index name. 'i', 'j', 'k' are tried until no name collision with
382 * an existing local variable occurs. If all names collide, <code>null</code> is returned.
384 public String getIndex() {
385 CompilationUnitCompletion completion= getCompletion();
386 String[] proposals= {"i", "j", "k"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
388 for (int i= 0; i != proposals.length; i++) {
389 String proposal = proposals[i];
391 if (!completion.existsLocalName(proposal))
399 * Returns the name of a local collection, <code>null</code> if no local collection
402 public String guessCollection() {
403 CompilationUnitCompletion completion= getCompletion();
405 LocalVariable[] localCollections= completion.findLocalCollections();
407 if (localCollections.length > 0)
408 return localCollections[localCollections.length - 1].name;
410 } catch (JavaModelException e) {
411 PHPeclipsePlugin.log(e);
418 * Returns an iterator name ('iter'). If 'iter' already exists as local variable,
419 * <code>null</code> is returned.
421 public String getIterator() {
422 CompilationUnitCompletion completion= getCompletion();
423 String[] proposals= {"iter"}; //$NON-NLS-1$
425 for (int i= 0; i != proposals.length; i++) {
426 String proposal = proposals[i];
428 if (!completion.existsLocalName(proposal))
436 // public void addIteratorImport() {
439 // CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings();
440 // ImportsStructure structure= new ImportsStructure(getCompilationUnit(), settings.importOrder, settings.importThreshold, true);
441 // structure.addImport("java.util.Iterator"); //$NON-NLS-1$
442 // structure.create(false, null);
444 // } catch (CoreException e) {
445 // handleException(null, e);
450 * Evaluates a 'java' template in thecontext of a compilation unit
452 public static String evaluateTemplate(Template template, ICompilationUnit compilationUnit, int position) throws CoreException {
454 ContextType contextType= ContextTypeRegistry.getInstance().getContextType("php"); //$NON-NLS-1$
455 if (contextType == null)
456 throw new CoreException(new Status(IStatus.ERROR, PHPeclipsePlugin.PLUGIN_ID, IStatus.ERROR, PHPTemplateMessages.getString("JavaContext.error.message"), null)); //$NON-NLS-1$
458 IDocument document= new Document();
459 // if (compilationUnit != null && compilationUnit.exists())
460 // document.set(compilationUnit.getSource());
462 JavaContext context= new JavaContext(contextType, document, position, 0, compilationUnit);
463 context.setForceEvaluation(true);
465 TemplateBuffer buffer= context.evaluate(template);
468 return buffer.getString();