Syntax highlighting is changeable.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / corext / template / php / JavaContext.java
index 2d50010..30cebda 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials 
  * are made available under the terms of the Common Public License v1.0
  * which accompanies this distribution, and is available at
@@ -13,15 +13,13 @@ package net.sourceforge.phpdt.internal.corext.template.php;
 import java.lang.reflect.InvocationTargetException;
 
 import net.sourceforge.phpdt.core.ICompilationUnit;
-import net.sourceforge.phpdt.core.JavaModelException;
 import net.sourceforge.phpdt.internal.corext.Assert;
-import net.sourceforge.phpdt.internal.corext.template.ContextType;
-import net.sourceforge.phpdt.internal.corext.template.ContextTypeRegistry;
-import net.sourceforge.phpdt.internal.corext.template.Template;
-import net.sourceforge.phpdt.internal.corext.template.TemplateBuffer;
-import net.sourceforge.phpdt.internal.corext.template.TemplateTranslator;
 import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitCompletion.LocalVariable;
+import net.sourceforge.phpdt.internal.corext.util.Strings;
+import net.sourceforge.phpdt.internal.ui.preferences.CodeFormatterPreferencePage;
+import net.sourceforge.phpdt.internal.ui.text.template.contentassist.MultiVariable;
 import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 
 import org.eclipse.core.runtime.CoreException;
@@ -32,12 +30,19 @@ import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.Document;
 import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateBuffer;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateTranslator;
+import org.eclipse.jface.text.templates.TemplateVariable;
 import org.eclipse.swt.widgets.Shell;
 
 /**
  * A context for java source.
  */
-public class JavaContext extends PHPUnitContext {
+public class JavaContext extends CompilationUnitContext {
 
        /** The platform default line delimiter. */
        private static final String PLATFORM_LINE_DELIMITER= System.getProperty("line.separator"); //$NON-NLS-1$
@@ -52,42 +57,51 @@ public class JavaContext extends PHPUnitContext {
         * @param document the document.
         * @param completionOffset the completion offset within the document.
         * @param completionLength the completion length.
-        * @param unit the compilation unit (may be <code>null</code>).
+        * @param compilationUnit the compilation unit (may be <code>null</code>).
         */
-       public JavaContext(ContextType type, IDocument document, int completionOffset, int completionLength,
+       public JavaContext(TemplateContextType type, IDocument document, int completionOffset, int completionLength,
                ICompilationUnit compilationUnit)
        {
-               super(type, document, completionOffset, completionLength); //, compilationUnit);
+               super(type, document, completionOffset, completionLength, compilationUnit);
        }
        
        /**
         * Returns the indentation level at the position of code completion.
         */
        private int getIndentation() {
-//             int start= getStart();
-//             IDocument document= getDocument();
-//             try {
-//                     IRegion region= document.getLineInformationOfOffset(start);
-//                     String lineContent= document.get(region.getOffset(), region.getLength());
+               int start= getStart();
+               IDocument document= getDocument();
+               try {
+                       IRegion region= document.getLineInformationOfOffset(start);
+                       String lineContent= document.get(region.getOffset(), region.getLength());
+                   return Strings.computeIndent(lineContent, CodeFormatterPreferencePage.getTabSize());
 //                     return Strings.computeIndent(lineContent, CodeFormatterUtil.getTabWidth());
-//             } catch (BadLocationException e) {
-//                     return 0;
-//             }
-return 0;
+               } catch (BadLocationException e) {
+                       return 0;
+               }
        }       
        
+       
+
        /*
         * @see TemplateContext#evaluate(Template template)
         */
-       public TemplateBuffer evaluate(Template template) throws CoreException {
+       public TemplateBuffer evaluate(Template template) throws BadLocationException, TemplateException {
 
                if (!canEvaluate(template))
-                       return null;
+                       throw new TemplateException(JavaTemplateMessages.getString("Context.error.cannot.evaluate")); //$NON-NLS-1$
                
-               TemplateTranslator translator= new TemplateTranslator();
-               TemplateBuffer buffer= translator.translate(template.getPattern());
+               TemplateTranslator translator= new TemplateTranslator() {
+                       /*
+                        * @see org.eclipse.jface.text.templates.TemplateTranslator#createVariable(java.lang.String, java.lang.String, int[])
+                        */
+                       protected TemplateVariable createVariable(String type, String name, int[] offsets) {
+                               return new MultiVariable(type, name, offsets);
+                       }
+               };
+               TemplateBuffer buffer= translator.translate(template);
 
-               getContextType().edit(buffer, this);
+               getContextType().resolve(buffer, this);
                        
                String lineDelimiter= null;
                try {
@@ -99,11 +113,11 @@ return 0;
                        lineDelimiter= PLATFORM_LINE_DELIMITER;
                        
                IPreferenceStore prefs= PHPeclipsePlugin.getDefault().getPreferenceStore();
-//             boolean useCodeFormatter= prefs.getBoolean(PreferenceConstants.TEMPLATES_USE_CODEFORMATTER);                    
-//             
-//             ITemplateEditor formatter= new JavaFormatter(lineDelimiter, getIndentation(), useCodeFormatter);
-//             formatter.edit(buffer, this);
-
+               boolean useCodeFormatter= prefs.getBoolean(PreferenceConstants.TEMPLATES_USE_CODEFORMATTER);                    
+               
+//             JavaFormatter formatter= new JavaFormatter(lineDelimiter, getIndentation(), useCodeFormatter);
+//             formatter.format(buffer, this);
+               
                return buffer;
        }
        
@@ -117,10 +131,15 @@ return 0;
                        return true;
 
                return
-                       template.matches(key, getContextType().getName()) &&
+                       template.matches(key, getContextType().getId()) &&
                        key.length() != 0 && template.getName().toLowerCase().startsWith(key.toLowerCase());
        }
 
+       public boolean canEvaluate(String identifier) {
+           String prefix = getKey();
+           return
+             identifier.toLowerCase().startsWith(prefix.toLowerCase());
+         }
        /*
         * @see DocumentTemplateContext#getCompletionPosition();
         */
@@ -163,11 +182,11 @@ return 0;
        }
 
        /*
-        * @see org.eclipse.jdt.internal.corext.template.DocumentTemplateContext#getEnd()
+        * @see net.sourceforge.phpdt.internal.corext.template.DocumentTemplateContext#getEnd()
         */
        public int getEnd() {
                
-               if (getCompletionLength() == 0)         
+               if (getCompletionLength() == 0)
                        return super.getEnd();
 
                try {                   
@@ -187,7 +206,7 @@ return 0;
        }
 
        /*
-        * @see org.eclipse.jdt.internal.corext.template.DocumentTemplateContext#getKey()
+        * @see net.sourceforge.phpdt.internal.corext.template.DocumentTemplateContext#getKey()
         */
        public String getKey() {
 
@@ -224,28 +243,8 @@ return 0;
                }
        }
 
-       private CompilationUnitCompletion guessVariableNames() {
-//             ICompilationUnit unit= getCompilationUnit();
-//             int start= getStart();
-//             
-//             if (unit == null)
-//                     return null;
-//             
-//             try {
-//                     CompilationUnitCompletion collector= new CompilationUnitCompletion(unit);
-//                     unit.codeComplete(start, collector);                    
-//                     return collector;
-//             
-//             } catch (JavaModelException e) {
-//                     handleException(null, e);
-//                     return null;
-//             }
-    return null;
-       }       
-       
-       
        private static void handleException(Shell shell, Exception e) {
-               String title= PHPTemplateMessages.getString("JavaContext.error.title"); //$NON-NLS-1$
+               String title= JavaTemplateMessages.getString("JavaContext.error.title"); //$NON-NLS-1$
                if (e instanceof CoreException)
                        ExceptionHandler.handle((CoreException)e, shell, title, null);
                else if (e instanceof InvocationTargetException)
@@ -256,7 +255,7 @@ return 0;
                }
        }       
 
-       private CompilationUnitCompletion getCompletion() {
+//     private CompilationUnitCompletion getCompletion() {
 //             ICompilationUnit compilationUnit= getCompilationUnit();
 //             if (fCompletion == null) {
 //                     fCompletion= new CompilationUnitCompletion(compilationUnit);
@@ -271,48 +270,95 @@ return 0;
 //             }
 //             
 //             return fCompletion;
-    return null;
-       }
+//     }
 
        /**
         * Returns the name of a guessed local array, <code>null</code> if no local
         * array exists.
         */
-       public String guessArray() {
-               CompilationUnitCompletion completion= getCompletion();
-               LocalVariable[] localArrays= completion.findLocalArrays();
-                               
-               if (localArrays.length > 0)
-                       return localArrays[localArrays.length - 1].name;
-
-               return null;    
+//     public String guessArray() {
+//             return firstOrNull(guessArrays());
+//     }
+       
+       /**
+        * Returns the name of a guessed local array, <code>null</code> if no local
+        * array exists.
+        */
+//     public String[] guessArrays() {
+//             CompilationUnitCompletion completion= getCompletion();
+//             LocalVariable[] localArrays= completion.findLocalArrays();
+//                             
+//             String[] ret= new String[localArrays.length];
+//             for (int i= 0; i < ret.length; i++) {
+//                     ret[ret.length - i - 1]= localArrays[i].name;
+//             }
+//             return ret;
+//     }
+       
+       /**
+        * Returns the name of the type of a local array, <code>null</code> if no local
+        * array exists.
+        */
+//     public String guessArrayType() {
+//             return firstOrNull(guessArrayTypes());
+//     }
+       
+       private String firstOrNull(String[] strings) {
+               if (strings.length > 0)
+                       return strings[0];
+               else
+                       return null;
        }
        
        /**
         * Returns the name of the type of a local array, <code>null</code> if no local
         * array exists.
         */
-       public String guessArrayType() {
-               CompilationUnitCompletion completion= getCompletion();
-               LocalVariable[] localArrays= completion.findLocalArrays();
-                               
-               if (localArrays.length > 0) {
-                       LocalVariable localArray= localArrays[localArrays.length - 1];                  
-
-                       String arrayTypeName= localArray.typeName;
+//     public String[][] guessGroupedArrayTypes() {
+//             CompilationUnitCompletion completion= getCompletion();
+//             LocalVariable[] localArrays= completion.findLocalArrays();
+//             
+//             String[][] ret= new String[localArrays.length][];
+//             
+//             for (int i= 0; i < localArrays.length; i++) {
+//                     String type= getArrayTypeFromLocalArray(completion, localArrays[localArrays.length - i - 1]);
+//                     ret[i]= new String[] {type};
+//             }
+//             
+//             return ret;
+//     }
+       
+       /**
+        * Returns the name of the type of a local array, <code>null</code> if no local
+        * array exists.
+        */
+//     public String[] guessArrayTypes() {
+//             CompilationUnitCompletion completion= getCompletion();
+//             LocalVariable[] localArrays= completion.findLocalArrays();
+//             
+//             List ret= new ArrayList();
+//             
+//             for (int i= 0; i < localArrays.length; i++) {
+//                     String type= getArrayTypeFromLocalArray(completion, localArrays[localArrays.length - i - 1]);
+//                     if (!ret.contains(type))
+//                             ret.add(type);
+//             }
+//             
+//             return (String[]) ret.toArray(new String[ret.size()]);
+//     }
+       
+       private String getArrayTypeFromLocalArray(CompilationUnitCompletion completion, LocalVariable array) {
+                       String arrayTypeName= array.typeName;
                        String typeName= getScalarType(arrayTypeName);
                        int dimension= getArrayDimension(arrayTypeName) - 1;
                        Assert.isTrue(dimension >= 0);
                        
-                       String qualifiedName= createQualifiedTypeName(localArray.typePackageName, typeName);
+                       String qualifiedName= createQualifiedTypeName(array.typePackageName, typeName);
                        String innerTypeName= completion.simplifyTypeName(qualifiedName);
                        
                        return innerTypeName == null
                                ? createArray(typeName, dimension)
                                : createArray(innerTypeName, dimension);
-               }
-               
-               return null;
        }
        
        private static String createArray(String type, int dimension) {
@@ -355,109 +401,212 @@ return 0;
         * Returns a proposal for a variable name of a local array element, <code>null</code>
         * if no local array exists.
         */
-       public String guessArrayElement() {
+//     public String guessArrayElement() {
+//             return firstOrNull(guessArrayElements());
+//     }
+       /**
+        * Returns a proposal for a variable name of a local array element, <code>null</code>
+        * if no local array exists.
+        */
+//     public String[] guessArrayElements() {
+//             ICompilationUnit cu= getCompilationUnit();
+//             if (cu == null) {
+//                     return new String[0];
+//             }
+//             
 //             CompilationUnitCompletion completion= getCompletion();
 //             LocalVariable[] localArrays= completion.findLocalArrays();
 //             
-//             if (localArrays.length > 0) {
-//                     int idx= localArrays.length - 1;
+//             List ret= new ArrayList();
+//             
+//             for (int i= 0; i < localArrays.length; i++) {
+//                     int idx= localArrays.length - i - 1;
 //                     
 //                     LocalVariable var= localArrays[idx];
 //                     
-//                     IJavaProject project= getCompilationUnit().getJavaProject();
+//                     IJavaProject project= cu.getJavaProject();
 //                     String typeName= var.typeName;
 //                     String baseTypeName= typeName.substring(0, typeName.lastIndexOf('['));
 //
-//                     String[] proposals= NamingConventions.suggestLocalVariableNames(project, var.typePackageName, baseTypeName, 0, completion.getLocalVariableNames());
-//                     if (proposals.length > 0) {
-//                             return proposals[0];
+//                     String indexName= getIndex();
+//                     String[] excludedNames= completion.getLocalVariableNames();
+//                     if (indexName != null) {
+//                             ArrayList excludedNamesList= new ArrayList(Arrays.asList(excludedNames));
+//                             excludedNamesList.add(indexName);
+//                             excludedNames= (String[])excludedNamesList.toArray(new String[excludedNamesList.size()]);
+//                     }
+//                     String[] proposals= NamingConventions.suggestLocalVariableNames(project, var.typePackageName, baseTypeName, 0, excludedNames);
+//                     for (int j= 0; j < proposals.length; j++) {
+//                             if (!ret.contains(proposals[j]))
+//                                     ret.add(proposals[j]);
 //                     }
 //             }
+//             
+//             return (String[]) ret.toArray(new String[ret.size()]);
+//     }
 
-               return null;
-       }
+       /**
+        * Returns a proposal for a variable name of a local array element, <code>null</code>
+        * if no local array exists.
+        */
+//     public String[][] guessGroupedArrayElements() {
+//             ICompilationUnit cu= getCompilationUnit();
+//             if (cu == null) {
+//                     return new String[0][];
+//             }
+//             
+//             CompilationUnitCompletion completion= getCompletion();
+//             LocalVariable[] localArrays= completion.findLocalArrays();
+//             
+//             String[][] ret= new String[localArrays.length][];
+//             
+//             for (int i= 0; i < localArrays.length; i++) {
+//                     int idx= localArrays.length - i - 1;
+//                     
+//                     LocalVariable var= localArrays[idx];
+//                     
+//                     IJavaProject project= cu.getJavaProject();
+//                     String typeName= var.typeName;
+//                     int dim= -1; // we expect at least one array
+//                     int lastIndex= typeName.length();
+//                     int bracket= typeName.lastIndexOf('[');
+//                     while (bracket != -1) {
+//                             lastIndex= bracket;
+//                             dim++;
+//                             bracket= typeName.lastIndexOf('[', bracket - 1);
+//                     }
+//                     typeName= typeName.substring(0, lastIndex);
+//                     
+//                     String indexName= getIndex();
+//                     String[] excludedNames= completion.getLocalVariableNames();
+//                     if (indexName != null) {
+//                             ArrayList excludedNamesList= new ArrayList(Arrays.asList(excludedNames));
+//                             excludedNamesList.add(indexName);
+//                             excludedNames= (String[])excludedNamesList.toArray(new String[excludedNamesList.size()]);
+//                     }
+//                     String[] proposals= NamingConventions.suggestLocalVariableNames(project, var.typePackageName, typeName, dim, excludedNames);
+//                     
+//                     ret[i]= proposals;
+//             }
+//             
+//             return ret;
+//     }
 
        /**
         * Returns an array index name. 'i', 'j', 'k' are tried until no name collision with
         * an existing local variable occurs. If all names collide, <code>null</code> is returned.
         */     
-       public String getIndex() {
-               CompilationUnitCompletion completion= getCompletion();
-               String[] proposals= {"i", "j", "k"};  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-               
-               for (int i= 0; i != proposals.length; i++) {
-                       String proposal = proposals[i];
-
-                       if (!completion.existsLocalName(proposal))
-                               return proposal;
-               }
-
-               return null;
-       }
+//     public String getIndex() {
+//             CompilationUnitCompletion completion= getCompletion();
+//             String[] proposals= {"i", "j", "k"};  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+//             
+//             for (int i= 0; i != proposals.length; i++) {
+//                     String proposal = proposals[i];
+//
+//                     if (!completion.existsLocalName(proposal))
+//                             return proposal;
+//             }
+//
+//             return null;
+//     }
        
        /**
         * Returns the name of a local collection, <code>null</code> if no local collection
         * exists.
         */
-       public String guessCollection() {
-               CompilationUnitCompletion completion= getCompletion();
-               try {
-                       LocalVariable[] localCollections= completion.findLocalCollections();
-               
-                       if (localCollections.length > 0)
-                               return localCollections[localCollections.length - 1].name;
-
-               } catch (JavaModelException e) {
-                       PHPeclipsePlugin.log(e);
-               }
-
-               return null;
-       }
+//     public String guessCollection() {
+//             return firstOrNull(guessCollections());
+//     }
+       
+       /**
+        * Returns the names of local collections.
+        */
+//     public String[] guessCollections() {
+//             CompilationUnitCompletion completion= getCompletion();
+//             try {
+//                     LocalVariable[] localCollections= completion.findLocalCollections();
+//                     String[] ret= new String[localCollections.length];
+//                     for (int i= 0; i < ret.length; i++) {
+//                             ret[ret.length - i - 1]= localCollections[i].name;
+//                     }
+//                     
+//                     return ret;
+//
+//             } catch (JavaModelException e) {
+//                     JavaPlugin.log(e);
+//             }
+//
+//             return new String[0];
+//     }
+       
 
        /**
         * Returns an iterator name ('iter'). If 'iter' already exists as local variable,
         * <code>null</code> is returned.
         */
-       public String getIterator() {
-               CompilationUnitCompletion completion= getCompletion();          
-               String[] proposals= {"iter"}; //$NON-NLS-1$
-               
-               for (int i= 0; i != proposals.length; i++) {
-                       String proposal = proposals[i];
-
-                       if (!completion.existsLocalName(proposal))
-                               return proposal;
-               }
-
-               return null;
-       }
+//     public String getIterator() {
+//             CompilationUnitCompletion completion= getCompletion();          
+//             String[] proposals= {"iter"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+//             
+//             for (int i= 0; i != proposals.length; i++) {
+//                     String proposal = proposals[i];
+//
+//                     if (!completion.existsLocalName(proposal))
+//                             return proposal;
+//             }
+//
+//             return null;
+//     }
 
 
 //     public void addIteratorImport() {
+//             ICompilationUnit cu= getCompilationUnit();
+//             if (cu == null) {
+//                     return;
+//             }
 //     
 //             try {
+//                     Position position= new Position(getCompletionOffset(), getCompletionLength());
+//                     IDocument document= getDocument();
+//                     final String category= "__template_position_importer" + System.currentTimeMillis(); //$NON-NLS-1$
+//                     IPositionUpdater updater= new DefaultPositionUpdater(category);
+//                     document.addPositionCategory(category);
+//                     document.addPositionUpdater(updater);
+//                     document.addPosition(position);
+//
 //                     CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings();
-//                     ImportsStructure structure= new ImportsStructure(getCompilationUnit(), settings.importOrder, settings.importThreshold, true);
+//                     ImportsStructure structure= new ImportsStructure(cu, settings.importOrder, settings.importThreshold, true);
 //                     structure.addImport("java.util.Iterator"); //$NON-NLS-1$
 //                     structure.create(false, null);
 //
+//                     document.removePosition(position);
+//                     document.removePositionUpdater(updater);
+//                     document.removePositionCategory(category);
+//                     
+//                     setCompletionOffset(position.getOffset());
+//                     setCompletionLength(position.getLength());
+//                     
 //             } catch (CoreException e) {
 //                     handleException(null, e);
+//             } catch (BadLocationException e) {
+//                     handleException(null, e);
+//             } catch (BadPositionCategoryException e) {
+//                     handleException(null, e);
 //             }
 //     }
        
        /**
         * Evaluates a 'java' template in thecontext of a compilation unit
         */
-       public static String evaluateTemplate(Template template, ICompilationUnit compilationUnit, int position) throws CoreException {
+       public static String evaluateTemplate(Template template, ICompilationUnit compilationUnit, int position) throws CoreException, BadLocationException, TemplateException {
 
-               ContextType contextType= ContextTypeRegistry.getInstance().getContextType("php"); //$NON-NLS-1$
+               TemplateContextType contextType= PHPeclipsePlugin.getDefault().getTemplateContextRegistry().getContextType("java"); //$NON-NLS-1$
                if (contextType == null)
-                       throw new CoreException(new Status(IStatus.ERROR, PHPeclipsePlugin.PLUGIN_ID, IStatus.ERROR, PHPTemplateMessages.getString("JavaContext.error.message"), null)); //$NON-NLS-1$
+                       throw new CoreException(new Status(IStatus.ERROR, PHPeclipsePlugin.PLUGIN_ID, IStatus.ERROR, JavaTemplateMessages.getString("JavaContext.error.message"), null)); //$NON-NLS-1$
 
                IDocument document= new Document();
-//             if (compilationUnit != null && compilationUnit.exists())
-//                     document.set(compilationUnit.getSource());
+               if (compilationUnit != null && compilationUnit.exists())
+                       document.set(compilationUnit.getSource());
 
                JavaContext context= new JavaContext(contextType, document, position, 0, compilationUnit);
                context.setForceEvaluation(true);