From: Xavier Ducrohet <> Date: Wed, 15 Apr 2009 18:43:56 +0000 (-0700) Subject: AI 146352: am: CL 146351 Fix aidl 2 issues: aidl file change for parcelable didnt... X-Git-Tag: android-x86-2.2~610^2~450^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=faaf5fe19f95c233e32d820b66975e64cee123ca;p=android-x86%2Fsdk.git AI 146352: am: CL 146351 Fix aidl 2 issues: aidl file change for parcelable didnt trigger a recompilation. Folder creation failed if parent folder didn't exist. Original author: xav Merged from: //branches/cupcake/... Automated import of CL 146352 --- diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java index 9257f2557..df023b856 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java @@ -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. diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java index 29942e8c7..0a4829931 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java @@ -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 mAidlToCompile = new ArrayList(); @@ -107,6 +123,10 @@ class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements return mCompileResources; } + public boolean getForceAidlCompile() { + return mForceAidlCompile; + } + public ArrayList 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; + } }