OSDN Git Service

AI 146352: am: CL 146351 Fix aidl 2 issues: aidl file change for parcelable didnt...
authorXavier Ducrohet <>
Wed, 15 Apr 2009 18:43:56 +0000 (11:43 -0700)
committerThe Android Open Source Project <initial-contribution@android.com>
Wed, 15 Apr 2009 18:43:56 +0000 (11:43 -0700)
  Original author: xav
  Merged from: //branches/cupcake/...

Automated import of CL 146352

eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java

index 9257f25..df023b8 100644 (file)
@@ -27,6 +27,7 @@ import com.android.ide.eclipse.common.project.XmlErrorHandler.BasicXmlErrorListe
 import com.android.sdklib.IAndroidTarget;
 import com.android.sdklib.SdkConstants;
 
+import org.eclipse.core.resources.IContainer;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IMarker;
@@ -250,9 +251,13 @@ public class PreCompilerBuilder extends BaseBuilder {
                     // record the state
                     mMustCompileResources |= dv.getCompileResources();
                     
-                    // handle aidl modification, and update mMustCompileAidl
-                    mergeAidlFileModifications(dv.getAidlToCompile(),
-                            dv.getAidlToRemove());
+                    if (dv.getForceAidlCompile()) {
+                        buildAidlCompilationList(project, sourceFolderPathList);
+                    } else {
+                        // handle aidl modification, and update mMustCompileAidl
+                        mergeAidlFileModifications(dv.getAidlToCompile(),
+                                dv.getAidlToRemove());
+                    }
                     
                     // get the java package from the visitor
                     javaPackage = dv.getManifestPackage();
@@ -755,10 +760,9 @@ public class PreCompilerBuilder extends BaseBuilder {
         // get an IFolder for this path. It's relative to the 'gen' folder already
         IFolder destinationFolder = mGenFolder.getFolder(destinationPath);
         
-        // create it if needed
+        // create it if needed.
         if (destinationFolder.exists() == false && createFolders) {
-            destinationFolder.create(true /*force*/, true /*local*/,
-                    new SubProgressMonitor(monitor, 10));
+            createFolder(destinationFolder, monitor);
         }
         
         // Build the Java file name from the aidl name.
@@ -771,6 +775,29 @@ public class PreCompilerBuilder extends BaseBuilder {
     }
 
     /**
+     * Creates the destination folder. Because
+     * {@link IFolder#create(boolean, boolean, IProgressMonitor)} only works if the parent folder
+     * already exists, this goes and ensure that all the parent folders actually exist, or it 
+     * creates them as well.
+     * @param destinationFolder The folder to create
+     * @param monitor the {@link IProgressMonitor},
+     * @throws CoreException 
+     */
+    private void createFolder(IFolder destinationFolder, IProgressMonitor monitor)
+            throws CoreException {
+        
+        // check the parent exist and create if necessary.
+        IContainer parent = destinationFolder.getParent();
+        if (parent.getType() == IResource.FOLDER && parent.exists() == false) {
+            createFolder((IFolder)parent, monitor);
+        }
+
+        // create the folder.
+        destinationFolder.create(true /*force*/, true /*local*/,
+                new SubProgressMonitor(monitor, 10));
+    }
+
+    /**
      * Execute the aidl command line, parse the output, and mark the aidl file
      * with any reported errors.
      * @param command the String array containing the command line to execute.
index 29942e8..0a48299 100644 (file)
@@ -53,6 +53,17 @@ import java.util.ArrayList;
  */
 class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements
         IResourceDeltaVisitor {
+    
+    private enum AidlType {
+        UNKNOWN, INTERFACE, PARCELABLE;
+    }
+
+    // See comment in #getAidlType()
+//    private final static Pattern sParcelablePattern = Pattern.compile(
+//            "^\\s*parcelable\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*;\\s*$");
+//
+//    private final static Pattern sInterfacePattern = Pattern.compile(
+//            "^\\s*interface\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?:\\{.*)?$");
 
     // Result fields.
     /**
@@ -62,6 +73,11 @@ class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements
      * into R.java
      */
     private boolean mCompileResources = false;
+    
+    /**
+     * Aidl force recompilation flag. If true, we'll attempt to recompile all aidl files.
+     */
+    private boolean mForceAidlCompile = false;
 
     /** List of .aidl files found that are modified or new. */
     private final ArrayList<AidlData> mAidlToCompile = new ArrayList<AidlData>();
@@ -107,6 +123,10 @@ class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements
         return mCompileResources;
     }
 
+    public boolean getForceAidlCompile() {
+        return mForceAidlCompile;
+    }
+    
     public ArrayList<AidlData> getAidlToCompile() {
         return mAidlToCompile;
     }
@@ -302,7 +322,6 @@ class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements
                         AdtPlugin.printErrorToConsole(mBuilder.getProject(), msg);
                     }
                 }
-
             } else {
                 // this is another source folder.
                 // We only care about aidl files being added/modified/removed.
@@ -310,12 +329,21 @@ class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements
                 // get the extension of the resource
                 String ext = resource.getFileExtension();
                 if (AndroidConstants.EXT_AIDL.equalsIgnoreCase(ext)) {
-                    if (kind == IResourceDelta.REMOVED) {
-                        // we'll have to remove the generated file.
-                        mAidlToRemove.add(new AidlData(mSourceFolder, file));
+                    // first check whether it's a regular file or a parcelable.
+                    AidlType type = getAidlType(file);
+                    
+                    if (type == AidlType.INTERFACE) {
+                        if (kind == IResourceDelta.REMOVED) {
+                            // we'll have to remove the generated file.
+                            mAidlToRemove.add(new AidlData(mSourceFolder, file));
+                        } else if (mForceAidlCompile == false) {
+                            // add the aidl file to the list of file to (re)compile
+                            mAidlToCompile.add(new AidlData(mSourceFolder, file));
+                        }
                     } else {
-                        // add the aidl file to the list of file to (re)compile
-                        mAidlToCompile.add(new AidlData(mSourceFolder, file));
+                        // force recompilations of all Aidl Files.
+                        mForceAidlCompile = true;
+                        mAidlToCompile.clear();
                     }
                 }
             }
@@ -457,4 +485,56 @@ class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements
         
         return null;
     }
+    
+    /**
+     * Returns the type of the aidl file. Aidl files can either declare interfaces, or declare
+     * parcelables. This method will attempt to parse the file and return the type. If the type
+     * cannot be determined, then it will return {@link AidlType#UNKNOWN}.
+     * @param file The aidl file
+     * @return the type of the aidl.
+     * @throws CoreException
+     */
+    private AidlType getAidlType(IFile file) throws CoreException {
+        // At this time, parsing isn't available, so we return UNKNOWN. This will force
+        // a recompilation of all aidl file as soon as one is changed.
+        return AidlType.UNKNOWN;
+
+        // TODO: properly parse aidl file to determine type and generate dependency graphs.
+//
+//        String className = file.getName().substring(0,
+//                file.getName().length() - AndroidConstants.DOT_AIDL.length());
+//
+//        InputStream input = file.getContents(true /* force*/);
+//        try {
+//            BufferedReader reader = new BufferedReader(new InputStreamReader(input));
+//            String line;
+//            while ((line = reader.readLine()) != null) {
+//                if (line.length() == 0) {
+//                    continue;
+//                }
+//
+//                Matcher m = sParcelablePattern.matcher(line);
+//                if (m.matches() && m.group(1).equals(className)) {
+//                    return AidlType.PARCELABLE;
+//                }
+//
+//                m = sInterfacePattern.matcher(line);
+//                if (m.matches() && m.group(1).equals(className)) {
+//                    return AidlType.INTERFACE;
+//                }
+//            }
+//        } catch (IOException e) {
+//            throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+//                    "Error parsing aidl file", e));
+//        } finally {
+//            try {
+//                input.close();
+//            } catch (IOException e) {
+//                throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+//                        "Error parsing aidl file", e));
+//            }
+//        }
+//
+//        return AidlType.UNKNOWN;
+    }
 }