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;
// 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();
// 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.
}
/**
+ * 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.
*/
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.
/**
* 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>();
return mCompileResources;
}
+ public boolean getForceAidlCompile() {
+ return mForceAidlCompile;
+ }
+
public ArrayList<AidlData> getAidlToCompile() {
return mAidlToCompile;
}
AdtPlugin.printErrorToConsole(mBuilder.getProject(), msg);
}
}
-
} else {
// this is another source folder.
// We only care about aidl files being added/modified/removed.
// 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();
}
}
}
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;
+ }
}