summaryrefslogtreecommitdiffstats
path: root/eclipse/plugins
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2011-01-31 13:09:08 -0800
committerXavier Ducrohet <xav@android.com>2011-01-31 19:44:26 -0800
commitdec739da5551ddf52a8f3cff06c63de4aced2578 (patch)
tree9c89babb587086cb6b798e3f1aac2028000a2417 /eclipse/plugins
parent5f9527877e04cb6ce88c6178d67561a90bcee7dd (diff)
downloaddevice_generic_opengl-transport-dec739da5551ddf52a8f3cff06c63de4aced2578.tar.gz
device_generic_opengl-transport-dec739da5551ddf52a8f3cff06c63de4aced2578.tar.bz2
device_generic_opengl-transport-dec739da5551ddf52a8f3cff06c63de4aced2578.zip
Change the JavaGenerator to handle output and dependencies.
Previously, the generator only handled a list of files to compile and a list of files that were removed. Now the Generator provides all that needed to do incremental builders with known state. On top of providing a default deltavisitor it handles file dependency and list of output files. The aidl generator was updated to use this, and the renderscript generator will use the same mechanism. Also fixed the abortOnBadSetup which through CoreException which did nothing to stop later builders (unlike my comments said) and poluted the workspace log with worthless messages. Change-Id: Ib954beb9674f1387c022f926388adb8faf6cdac2
Diffstat (limited to 'eclipse/plugins')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AndroidConstants.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AidlGenerator.java346
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/GeneratorDeltaVisitor.java112
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/JavaGenerator.java396
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/NonJavaFileBundle.java101
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java52
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java28
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerDeltaVisitor.java6
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java63
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerDeltaVisitor.java22
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ResourceManagerBuilder.java22
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java5
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java3
14 files changed, 662 insertions, 498 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AndroidConstants.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AndroidConstants.java
index 44c36595b..d73308046 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AndroidConstants.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AndroidConstants.java
@@ -72,6 +72,8 @@ public class AndroidConstants {
public final static String EXT_JAR = "jar"; //$NON-NLS-1$
/** Extension of aidl files, i.e. "aidl" */
public final static String EXT_AIDL = "aidl"; //$NON-NLS-1$
+ /** Extension of Renderscript files, i.e. "rs" */
+ public final static String EXT_RS = "rs"; //$NON-NLS-1$
/** Extension of native libraries, i.e. "so" */
public final static String EXT_NATIVE_LIB = "so"; //$NON-NLS-1$
/** Extension of dex files, i.e. "dex" */
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AidlGenerator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AidlGenerator.java
index e28cc12ed..24b5b6728 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AidlGenerator.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AidlGenerator.java
@@ -22,7 +22,6 @@ import com.android.ide.eclipse.adt.internal.build.builders.BaseBuilder;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
import com.android.sdklib.IAndroidTarget;
import org.eclipse.core.resources.IContainer;
@@ -31,18 +30,18 @@ import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.IJavaProject;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -76,99 +75,25 @@ public class AidlGenerator extends JavaGenerator {
// "^\\s*interface\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?:\\{.*)?$");
- /**
- * The custom delta visitor for aidl files. Based on the base JavaGenerator's delta visitor.
- */
- public static class AidlGeneratorDeltaVisitor extends JavaGeneratorDeltaVisitor {
-
- @Override
- public void handleChangedNonJavaFile(IFolder currentSourceFolder, IFile file, int kind) {
- // get the extension of the resource
- String ext = file.getFileExtension();
- if (AndroidConstants.EXT_AIDL.equalsIgnoreCase(ext)) {
- // 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.
- addFileToRemove(currentSourceFolder, file);
- } else if (getForceCompile() == false) {
- // add the aidl file to the list of file to (re)compile
- addFileToCompile(currentSourceFolder, file);
- }
- } else {
- // force recompilations of all Aidl Files.
- setForceCompile();
- //mAidlToCompile.clear();
- }
- }
- }
-
- @Override
- public boolean handleChangedGeneratedJavaFile(IFolder currentSourceFolder, IFile file,
- List<IPath> sourceFolders) {
-
- String fileName = file.getName();
- String[] segments = file.getFullPath().segments();
-
- // Look for the source aidl file in all the source folders that would match this given
- // java file.
- String aidlFileName = fileName.replaceAll(AndroidConstants.RE_JAVA_EXT,
- AndroidConstants.DOT_AIDL);
-
- for (IPath sourceFolderPath : sourceFolders) {
- // do not search in the current source folder as it is the 'gen' folder.
- if (sourceFolderPath.equals(currentSourceFolder.getFullPath())) {
- continue;
- }
-
- IFolder sourceFolder = getFolder(sourceFolderPath);
- if (sourceFolder != null) {
- // go recursively, segment by segment.
- // index starts at 2 (0 is project, 1 is 'gen'
- IFile sourceFile = findFile(sourceFolder, segments, 2, aidlFileName);
-
- if (sourceFile != null) {
- // found the source. add it to the list of files to compile
- addFileToCompile(currentSourceFolder, sourceFile);
- return true;
- }
- }
- }
-
- return false;
- }
- }
-
public AidlGenerator(IJavaProject javaProject, IFolder genFolder) {
- super(new AidlGeneratorDeltaVisitor(), genFolder);
-
- IProject project = javaProject.getProject();
-
- boolean mustCompileAidl = ProjectHelper.loadBooleanProperty(project,
- PROPERTY_COMPILE_AIDL, true /*defaultValue*/);
-
- // if we stored that we have to compile some aidl, we build the list that will compile them
- // all
- if (mustCompileAidl) {
- ArrayList<IPath> sourceFolderPathList = BaseProjectHelper.getSourceClasspaths(
- javaProject);
-
- buildCompilationList(project, sourceFolderPathList);
- }
+ super(javaProject, genFolder);
}
@Override
- public boolean compileFiles(BaseBuilder builder, IProject project, IAndroidTarget projectTarget,
- List<IPath> sourceFolders, IProgressMonitor monitor) throws CoreException {
- List<SourceData> toCompile = getToCompile();
- List<SourceData> toRemove = getToRemove();
+ protected String getExtension() {
+ return AndroidConstants.EXT_AIDL;
+ }
- if (toCompile.size() == 0 && toRemove.size() == 0) {
- return false;
- }
+ @Override
+ protected String getSavePropertyName() {
+ return PROPERTY_COMPILE_AIDL;
+ }
+ @Override
+ protected void doCompileFiles(List<IFile> sources, BaseBuilder builder,
+ IProject project, IAndroidTarget projectTarget,
+ List<IPath> sourceFolders, List<IFile> notCompiledOut, IProgressMonitor monitor)
+ throws CoreException {
// create the command line
String[] command = new String[4 + sourceFolders.size()];
int index = 0;
@@ -183,68 +108,81 @@ public class AidlGenerator extends JavaGenerator {
command[index++] = "-I" + f.getLocation().toOSString(); //$NON-NLS-1$
}
- // list of files that have failed compilation.
- List<SourceData> stillNeedCompilation = new ArrayList<SourceData>();
-
- // if an aidl file is being removed before we managed to compile it, it'll be in
- // both list. We *need* to remove it from the compile list or it'll never go away.
- for (SourceData aidlFile : toRemove) {
- int pos = toCompile.indexOf(aidlFile);
- if (pos != -1) {
- toCompile.remove(pos);
+ // loop until we've compile them all
+ for (IFile sourceFile : sources) {
+ if (AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE) {
+ String name = sourceFile.getName();
+ IPath sourceFolderPath = getSourceFolderFor(sourceFile);
+ if (sourceFolderPath != null) {
+ // make a path to the source file relative to the source folder.
+ IPath relative = sourceFile.getFullPath().makeRelativeTo(sourceFolderPath);
+ name = relative.toString();
+ }
+ AdtPlugin.printToConsole(project, "AIDL: " + name);
}
- }
- // loop until we've compile them all
- for (SourceData aidlData : toCompile) {
// Remove the AIDL error markers from the aidl file
- builder.removeMarkersFromFile(aidlData.sourceFile, AndroidConstants.MARKER_AIDL);
+ builder.removeMarkersFromFile(sourceFile, AndroidConstants.MARKER_AIDL);
// get the path of the source file.
- IPath sourcePath = aidlData.sourceFile.getLocation();
+ IPath sourcePath = sourceFile.getLocation();
String osSourcePath = sourcePath.toOSString();
- IFile javaFile = getGenDestinationFile(aidlData, true /*createFolders*/, monitor);
+ // look if we already know the output
+ NonJavaFileBundle bundle = getBundle(sourceFile);
+ if (bundle == null) {
+ IFile javaFile = getAidlOutputFile(sourceFile, true /*createFolders*/, monitor);
+ bundle = new NonJavaFileBundle(sourceFile, javaFile);
+ addBundle(bundle);
+ }
// finish to set the command line.
command[index] = osSourcePath;
- command[index + 1] = javaFile.getLocation().toOSString();
+ command[index + 1] = bundle.getOutput().getLocation().toOSString();
// launch the process
- if (execAidl(builder, project, command, aidlData.sourceFile) == false) {
+ if (execAidl(builder, project, command, sourceFile) == false) {
// aidl failed. File should be marked. We add the file to the list
// of file that will need compilation again.
- stillNeedCompilation.add(aidlData);
-
- // and we move on to the next one.
- continue;
+ notCompiledOut.add(sourceFile);
}
}
+ }
- // change the list to only contains the file that have failed compilation
- toCompile.clear();
- toCompile.addAll(stillNeedCompilation);
-
- // Remove the java files created from aidl files that have been removed.
- for (SourceData aidlData : toRemove) {
- IFile javaFile = getGenDestinationFile(aidlData, false /*createFolders*/, monitor);
- if (javaFile.exists()) {
- // This confirms the java file was generated by the builder,
- // we can delete the aidlFile.
- javaFile.getLocation().toFile().delete();
+ @Override
+ protected void doRemoveFiles(List<IFile> sources, IProgressMonitor monitor)
+ throws CoreException {
+ for (IFile sourceFile : sources) {
+ // look if we already know the output
+ NonJavaFileBundle bundle = getBundle(sourceFile);
+ if (bundle != null) {
+ IFile outputFile = bundle.getOutput();
+ if (outputFile != null && outputFile.exists()) {
+ // This confirms the java file was generated by the builder,
+ // we can delete the aidlFile.
+ outputFile.getLocation().toFile().delete();
+ }
}
}
+ }
- toRemove.clear();
-
- // store the build state. If there are any files that failed to compile, we will
- // force a full aidl compile on the next project open. (unless a full compilation succeed
- // before the project is closed/re-opened.)
- saveState(project);
+ @Override
+ protected void loadOutputAndDependencies() {
+ IProgressMonitor monitor = new NullProgressMonitor();
+ Collection<NonJavaFileBundle> bundles = getBundles();
+ for (NonJavaFileBundle bundle : bundles) {
+ try {
+ IFile javaFile = getAidlOutputFile(bundle.getSourceFile(),
+ false /*createFolders*/, monitor);
+ bundle.setOutputFile(javaFile);
+ } catch (CoreException e) {
+ // ignore, we're not asking to create the folder so this won't happen anyway.
+ }
- return true;
+ }
}
+
/**
* Execute the aidl command line, parse the output, and mark the aidl file
* with any reported errors.
@@ -256,7 +194,8 @@ public class AidlGenerator extends JavaGenerator {
private boolean execAidl(BaseBuilder builder, IProject project, String[] command, IFile file) {
// do the exec
try {
- if (AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE) {
+ boolean verbose = AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE;
+ if (verbose) {
StringBuilder sb = new StringBuilder();
for (String c : command) {
sb.append(c);
@@ -279,13 +218,20 @@ public class AidlGenerator extends JavaGenerator {
// If the process failed and we couldn't parse the output
// we print a message, mark the project and exit
- if (result != 0 && error == true) {
- // display the message in the console.
- AdtPlugin.printErrorToConsole(project, results.toArray());
+ if (result != 0) {
+
+ if (error || verbose) {
+ // display the message in the console.
+ if (error) {
+ AdtPlugin.printErrorToConsole(project, results.toArray());
+ } else {
+ AdtPlugin.printToConsole(project, results.toArray());
+ }
- // mark the project and exit
- BaseProjectHelper.markResource(project, AndroidConstants.MARKER_ADT,
- Messages.Unparsed_AIDL_Errors, IMarker.SEVERITY_ERROR);
+ // mark the project and exit
+ BaseProjectHelper.markResource(project, AndroidConstants.MARKER_ADT,
+ Messages.Unparsed_AIDL_Errors, IMarker.SEVERITY_ERROR);
+ }
return false;
}
} catch (IOException e) {
@@ -354,33 +300,6 @@ public class AidlGenerator extends JavaGenerator {
return false;
}
- @Override
- public void saveState(IProject project) {
- // TODO: Optimize by saving only the files that need compilation
- ProjectHelper.saveStringProperty(project, PROPERTY_COMPILE_AIDL,
- Boolean.toString(getToCompile().size() > 0));
- }
-
-
- /**
- * Goes through the build paths and fills the list of aidl files to compile
- * ({@link #mAidlToCompile}).
- * @param project The project.
- * @param sourceFolderPathList The list of source folder paths.
- * @param genFolder the gen folder
- */
- @Override
- protected void buildCompilationList(IProject project, List<IPath> sourceFolderPathList) {
- IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
- for (IPath sourceFolderPath : sourceFolderPathList) {
- IFolder sourceFolder = root.getFolder(sourceFolderPath);
- // we don't look in the 'gen' source folder as there will be no source in there.
- if (sourceFolder.exists() && sourceFolder.equals(getGenFolder()) == false) {
- scanFolderForAidl(sourceFolder, sourceFolder);
- }
- }
- }
-
/**
* Returns the {@link IFile} handle to the destination file for a given aidl source file
* ({@link AidlData}).
@@ -391,65 +310,60 @@ public class AidlGenerator extends JavaGenerator {
* @return the handle to the destination file.
* @throws CoreException
*/
- private IFile getGenDestinationFile(SourceData aidlData, boolean createFolders,
+ private IFile getAidlOutputFile(IFile sourceFile, boolean createFolders,
IProgressMonitor monitor) throws CoreException {
- // build the destination folder path.
- // Use the path of the source file, except for the path leading to its source folder,
- // and for the last segment which is the filename.
- int segmentToSourceFolderCount = aidlData.sourceFolder.getFullPath().segmentCount();
- IPath packagePath = aidlData.sourceFile.getFullPath().removeFirstSegments(
- segmentToSourceFolderCount).removeLastSegments(1);
- Path destinationPath = new Path(packagePath.toString());
-
- // get an IFolder for this path. It's relative to the 'gen' folder already
- IFolder destinationFolder = getGenFolder().getFolder(destinationPath);
-
- // create it if needed.
- if (destinationFolder.exists() == false && createFolders) {
- createFolder(destinationFolder, monitor);
- }
- // Build the Java file name from the aidl name.
- String javaName = aidlData.sourceFile.getName().replaceAll(AndroidConstants.RE_AIDL_EXT,
- AndroidConstants.DOT_JAVA);
+ IPath sourceFolderPath = getSourceFolderFor(sourceFile);
+
+ // this really shouldn't happen since the sourceFile must be in a source folder
+ // since it comes from the delta visitor
+ if (sourceFolderPath != null) {
+ // make a path to the source file relative to the source folder.
+ IPath relative = sourceFile.getFullPath().makeRelativeTo(sourceFolderPath);
+ // remove the file name. This is now the destination folder.
+ relative = relative.removeLastSegments(1);
+
+ // get an IFolder for this path.
+ IFolder destinationFolder = getGenFolder().getFolder(relative);
+
+ // create it if needed.
+ if (destinationFolder.exists() == false && createFolders) {
+ createFolder(destinationFolder, monitor);
+ }
+
+ // Build the Java file name from the aidl name.
+ String javaName = sourceFile.getName().replaceAll(
+ AndroidConstants.RE_AIDL_EXT, AndroidConstants.DOT_JAVA);
+
+ // get the resource for the java file.
+ IFile javaFile = destinationFolder.getFile(javaName);
+ return javaFile;
+ }
- // get the resource for the java file.
- IFile javaFile = destinationFolder.getFile(javaName);
- return javaFile;
+ return null;
}
- /**
- * Scans a folder and fills the list of aidl files to compile.
- * @param sourceFolder the root source folder.
- * @param folder The folder to scan.
- */
- private void scanFolderForAidl(IFolder sourceFolder, IFolder folder) {
- try {
- IResource[] members = folder.members();
- for (IResource r : members) {
- // get the type of the resource
- switch (r.getType()) {
- case IResource.FILE:
- // if this a file, check that the file actually exist
- // and that it's an aidl file
- if (r.exists() &&
- AndroidConstants.EXT_AIDL.equalsIgnoreCase(r.getFileExtension())) {
- addFileToCompile(sourceFolder, (IFile)r);
- }
- break;
- case IResource.FOLDER:
- // recursively go through children
- scanFolderForAidl(sourceFolder, (IFolder)r);
- break;
- default:
- // this would mean it's a project or the workspace root
- // which is unlikely to happen. we do nothing
- break;
- }
+ private IPath getSourceFolderFor(IFile file) {
+ // find the source folder for the class so that we can infer the package from the
+ // difference between the file and its source folder.
+ List<IPath> sourceFolders = BaseProjectHelper.getSourceClasspaths(getJavaProject());
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+
+ for (IPath sourceFolderPath : sourceFolders) {
+ IFolder sourceFolder = root.getFolder(sourceFolderPath);
+ // we don't look in the 'gen' source folder as there will be no source in there.
+ if (sourceFolder.exists() && sourceFolder.equals(getGenFolder()) == false) {
+ // look for the source file parent, until we find this source folder.
+ IResource parent = file;
+ while ((parent = parent.getParent()) != null) {
+ if (parent.equals(sourceFolder)) {
+ return sourceFolderPath;
+ }
+ }
}
- } catch (CoreException e) {
- // Couldn't get the members list for some reason. Just return.
}
+
+ return null;
}
/**
@@ -525,6 +439,4 @@ public class AidlGenerator extends JavaGenerator {
//
// return AidlType.UNKNOWN;
}
-
-
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java
index 4b395ace6..545d0f95a 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java
@@ -770,7 +770,7 @@ public class BuildHelper {
IJavaProject javaProject, IWorkspaceRoot wsRoot, ArrayList<String> list)
throws DuplicateFileException, ApkCreationException, SealedApkException, CoreException {
// get the source pathes
- ArrayList<IPath> sourceFolders = BaseProjectHelper.getSourceClasspaths(javaProject);
+ List<IPath> sourceFolders = BaseProjectHelper.getSourceClasspaths(javaProject);
// loop on them and then recursively go through the content looking for matching files.
for (IPath sourcePath : sourceFolders) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/GeneratorDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/GeneratorDeltaVisitor.java
new file mode 100644
index 000000000..8419b246b
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/GeneratorDeltaVisitor.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.internal.build;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Base delta visitor for the Java generator classes.
+ *
+ * It can be used as is, as long as the matching {@link JavaGenerator} properly implements
+ * its abstract methods, and the generator does not output resource files,
+ * or can be extended to provide custom implementation for:
+ * {@link #handleSourceFile(IFile, int)}
+ * {@link #handleGeneratedFile(IFile, int)}
+ * {@link #handleResourceFile(IFile, int)}
+ * {@link #filterResourceFolder(IContainer)}
+ *
+ * Note that this is not actually a {@link IResourceDeltaVisitor}, it's meant to be used by
+ * PreCompilerDeltaVisitor
+ */
+public class GeneratorDeltaVisitor {
+
+ private JavaGenerator mGenerator;
+
+ /** List of source files found that are modified or new. */
+ private final Set<IFile> mToCompile = new HashSet<IFile>();
+
+ /** List of source files that have been removed. */
+ private final Set<IFile> mRemoved = new HashSet<IFile>();
+
+ public boolean handleGeneratedFile(IFile file, int kind) {
+ if (kind == IResourceDelta.REMOVED || kind == IResourceDelta.CHANGED) {
+ IFile sourceFile = mGenerator.isOutput(file);
+ if (sourceFile != null) {
+ mToCompile.add(sourceFile);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void handleSourceFile(IFile file, int kind) {
+ // first the file itself if this is a match for the generator's extension
+ if (mGenerator.getExtension().equals(file.getFileExtension())) {
+ if (kind == IResourceDelta.REMOVED) {
+ mRemoved.add(file);
+ } else {
+ mToCompile.add(file);
+ }
+ }
+
+ // now the dependencies. In all case we compile the files that depend on the
+ // added/changed/removed file.
+ mToCompile.addAll(mGenerator.isDependency(file));
+ }
+
+ public void handleResourceFile(IFile file, int kind) {
+ if (filterResourceFolder(file.getParent())) {
+ handleGeneratedFile(file, kind);
+ }
+ }
+
+ protected boolean filterResourceFolder(IContainer parent) {
+ return false;
+ }
+
+ public void addFileToCompile(IFile file) {
+ mToCompile.add(file);
+ }
+
+ Set<IFile> getFilesToCompile() {
+ return mToCompile;
+ }
+
+ public void addRemovedFile(IFile file) {
+ mRemoved.add(file);
+ }
+
+ Set<IFile> getRemovedFiles() {
+ return mRemoved;
+ }
+
+ public void reset() {
+ mToCompile.clear();
+ mRemoved.clear();
+ }
+
+ void init(JavaGenerator generator) {
+ mGenerator = generator;
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/JavaGenerator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/JavaGenerator.java
index 1f9244d6f..73a18c62e 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/JavaGenerator.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/JavaGenerator.java
@@ -17,20 +17,27 @@
package com.android.ide.eclipse.adt.internal.build;
import com.android.ide.eclipse.adt.internal.build.builders.BaseBuilder;
+import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
+import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
import com.android.sdklib.IAndroidTarget;
-import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IJavaProject;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
* Base class to handle generated java code.
@@ -44,236 +51,279 @@ import java.util.List;
*/
public abstract class JavaGenerator {
- /**
- * Data to temporarily store source file information.
- */
- protected static class SourceData {
- IFile sourceFile;
- /** this is the root source folder, not the file parent. */
- IFolder sourceFolder;
-
- SourceData(IFolder sourceFolder, IFile sourceFile) {
- this.sourceFolder = sourceFolder;
- this.sourceFile = sourceFile;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((sourceFile == null) ? 0 : sourceFile.hashCode());
- result = prime * result + ((sourceFolder == null) ? 0 : sourceFolder.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- SourceData other = (SourceData) obj;
- if (sourceFile == null) {
- if (other.sourceFile != null)
- return false;
- } else if (!sourceFile.equals(other.sourceFile))
- return false;
- if (sourceFolder == null) {
- if (other.sourceFolder != null)
- return false;
- } else if (!sourceFolder.equals(other.sourceFolder))
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "SourceData [sourceFile=" //$NON-NLS-1$
- + sourceFile
- + ", sourceFolder=" //$NON-NLS-1$
- + sourceFolder
- + "]"; //$NON-NLS-1$
- }
- }
-
- /**
- * Base delta visitor for the Java generator classes.
- *
- * It provides storage for modified and deleted source files and a few other features.
- */
- public abstract static class JavaGeneratorDeltaVisitor {
+ /** List of all source files, their dependencies, and their output. */
+ private final Map<IFile, NonJavaFileBundle> mFiles = new HashMap<IFile, NonJavaFileBundle>();
- private IWorkspaceRoot mRoot;
+ private final IJavaProject mJavaProject;
+ private final IFolder mGenFolder;
+ private final GeneratorDeltaVisitor mDeltaVisitor;
- private boolean mForceCompile;
+ /** List of source files pending compilation at the next build */
+ private final List<IFile> mToCompile = new ArrayList<IFile>();
- /** List of source files found that are modified or new. */
- private final List<SourceData> mToCompile = new ArrayList<SourceData>();
+ /** List of removed source files pending cleaning at the next build. */
+ private final List<IFile> mRemoved = new ArrayList<IFile>();
- /** List of .aidl files that have been removed. */
- private final List<SourceData> mToRemove = new ArrayList<SourceData>();
+ protected JavaGenerator(IJavaProject javaProject, IFolder genFolder,
+ GeneratorDeltaVisitor deltaVisitor) {
+ mJavaProject = javaProject;
+ mGenFolder = genFolder;
+ mDeltaVisitor = deltaVisitor;
- public abstract boolean handleChangedGeneratedJavaFile(IFolder currentSourceFolder,
- IFile file, List<IPath> sourceFolders);
+ mDeltaVisitor.init(this);
- public abstract void handleChangedNonJavaFile(IFolder currentSourceFolder,
- IFile file, int kind);
+ IProject project = javaProject.getProject();
- public void setWorkspaceRoot(IWorkspaceRoot root) {
- mRoot = root;
- }
+ // get all the source files
+ buildSourceFileList();
- public void setForceCompile() {
- mForceCompile = true;
- }
+ // load the known dependencies
+ loadOutputAndDependencies();
- boolean getForceCompile() {
- return mForceCompile;
- }
+ boolean mustCompile = loadState(project);
- public void addFileToCompile(IFolder sourceFolder, IFile sourceFile) {
- mToCompile.add(new SourceData(sourceFolder, sourceFile));
+ // if we stored that we have to compile some files, we build the list that will compile them
+ // all. For now we have to reuse the full list since we don't know which files needed
+ // compilation.
+ if (mustCompile) {
+ mToCompile.addAll(mFiles.keySet());
}
+ }
- List<SourceData> getFilesToCompile() {
- return mToCompile;
- }
+ protected JavaGenerator(IJavaProject javaProject, IFolder genFolder) {
+ this(javaProject, genFolder, new GeneratorDeltaVisitor());
+ }
- public void addFileToRemove(IFolder sourceFolder, IFile sourceFile) {
- mToRemove.add(new SourceData(sourceFolder, sourceFile));
- }
- List<SourceData> getFilesToRemove() {
- return mToRemove;
+ /**
+ * Returns whether the given file is an output of this generator by return the source
+ * file that generated it.
+ * @param file the file to test.
+ * @return the source file that generated the given file or null.
+ */
+ IFile isOutput(IFile file) {
+ for (NonJavaFileBundle bundle : mFiles.values()) {
+ if (bundle.generated(file)) {
+ return bundle.getSourceFile();
+ }
}
- public void reset() {
- mForceCompile = false;
- mToCompile.clear();
- mToRemove.clear();
- }
+ return null;
+ }
- /**
- * Returns a handle to the folder identified by the given path in this container.
- * <p/>The different with {@link IContainer#getFolder(IPath)} is that this returns a non
- * null object only if the resource actually exists and is a folder (and not a file)
- * @param path the path of the folder to return.
- * @return a handle to the folder if it exists, or null otherwise.
- */
- protected IFolder getFolder(IPath path) {
- IResource resource = mRoot.findMember(path);
- if (resource != null && resource.exists() && resource.getType() == IResource.FOLDER) {
- return (IFolder)resource;
+ /**
+ * Returns whether the given file is a dependency for other files by returning a list
+ * of file depending on the given file.
+ * @param file the file to test.
+ * @return a list of files that depend on the given file or an empty list if there
+ * are no matches.
+ */
+ List<IFile> isDependency(IFile file) {
+ ArrayList<IFile> files = new ArrayList<IFile>();
+ for (NonJavaFileBundle bundle : mFiles.values()) {
+ if (bundle.dependsOn(file)) {
+ files.add(bundle.getSourceFile());
}
-
- return null;
}
- /**
- * Searches for and return a file in a folder. The file is defined by its segments, and
- * a new name (replacing the last segment).
- * @param folder the folder we are searching
- * @param segments the segments of the file to search.
- * @param index the index of the current segment we are looking for
- * @param filename the new name to replace the last segment.
- * @return the {@link IFile} representing the searched file, or null if not found
- */
- protected IFile findFile(IFolder folder, String[] segments, int index, String filename) {
- boolean lastSegment = index == segments.length - 1;
- IResource resource = folder.findMember(lastSegment ? filename : segments[index]);
- if (resource != null && resource.exists()) {
- if (lastSegment) {
- if (resource.getType() == IResource.FILE) {
- return (IFile)resource;
- }
- } else {
- if (resource.getType() == IResource.FOLDER) {
- return findFile((IFolder)resource, segments, index+1, filename);
- }
- }
- }
- return null;
- }
+ return files;
}
- /** List of source files found that are modified or new. */
- private final List<SourceData> mToCompile = new ArrayList<SourceData>();
-
- /** List of .aidl files that have been removed. */
- private final List<SourceData> mToRemove = new ArrayList<SourceData>();
-
- private final JavaGeneratorDeltaVisitor mDeltaVisitor;
+ void addBundle(NonJavaFileBundle bundle) {
+ mFiles.put(bundle.getSourceFile(), bundle);
+ }
- private final IFolder mGenFolder;
+ NonJavaFileBundle getBundle(IFile file) {
+ return mFiles.get(file);
+ }
- protected JavaGenerator(JavaGeneratorDeltaVisitor deltaVisitor, IFolder genFolder) {
- mDeltaVisitor = deltaVisitor;
- mGenFolder = genFolder;
+ Collection<NonJavaFileBundle> getBundles() {
+ return mFiles.values();
}
- public JavaGeneratorDeltaVisitor getDeltaVisitor() {
+ public final GeneratorDeltaVisitor getDeltaVisitor() {
return mDeltaVisitor;
}
- IFolder getGenFolder() {
+ final IJavaProject getJavaProject() {
+ return mJavaProject;
+ }
+
+ final IFolder getGenFolder() {
return mGenFolder;
}
- List<SourceData> getToCompile() {
+ final List<IFile> getToCompile() {
return mToCompile;
}
- List<SourceData> getToRemove() {
- return mToRemove;
+ final List<IFile> getRemovedFile() {
+ return mRemoved;
}
- void addFileToCompile(IFolder sourceFolder, IFile sourceFile) {
- mToCompile.add(new SourceData(sourceFolder, sourceFile));
+ final void addFileToCompile(IFile file) {
+ mToCompile.add(file);
}
- public void prepareFullBuild(IProject project, List<IPath> sourceFolders) {
+ public final void prepareFullBuild(IProject project) {
mDeltaVisitor.reset();
- buildCompilationList(project, sourceFolders);
+
+ // get all the source files
+ buildSourceFileList();
+
+ mToCompile.addAll(mFiles.keySet());
}
- public void doneVisiting(IProject project, List<IPath> sourceFolders) {
- if (mDeltaVisitor.getForceCompile()) {
- buildCompilationList(project, sourceFolders);
- } else {
- // merge the previous file modification lists and the new one.
- mergeFileModifications(mDeltaVisitor);
- }
+ public final void doneVisiting(IProject project) {
+ // merge the previous file modification lists and the new one.
+ mergeFileModifications(mDeltaVisitor);
mDeltaVisitor.reset();
saveState(project);
}
- protected abstract void buildCompilationList(IProject project, List<IPath> sourceFolders);
+ protected abstract String getExtension();
+
+ protected abstract String getSavePropertyName();
+
+ public final boolean compileFiles(BaseBuilder builder,
+ IProject project, IAndroidTarget projectTarget,
+ List<IPath> sourceFolders, IProgressMonitor monitor) throws CoreException {
+
+ if (mToCompile.size() == 0 && mRemoved.size() == 0) {
+ return false;
+ }
+
+ // if a source file is being removed before we managed to compile it, it'll be in
+ // both list. We *need* to remove it from the compile list or it'll never go away.
+ for (IFile sourceFile : mRemoved) {
+ int pos = mToCompile.indexOf(sourceFile);
+ if (pos != -1) {
+ mToCompile.remove(pos);
+ }
+ }
+
+ // list of files that have failed compilation.
+ List<IFile> stillNeedCompilation = new ArrayList<IFile>();
+
+ doCompileFiles(mToCompile, builder, project, projectTarget, sourceFolders,
+ stillNeedCompilation, monitor);
+
+ mToCompile.clear();
+ mToCompile.addAll(stillNeedCompilation);
+
+ // Remove the files created from source files that have been removed.
+ doRemoveFiles(mRemoved, monitor);
+
+ // remove the associated bundles.
+ for (IFile removedFile : mRemoved) {
+ mFiles.remove(removedFile);
+ }
+
+ mRemoved.clear();
+
+ // store the build state. If there are any files that failed to compile, we will
+ // force a full aidl compile on the next project open. (unless a full compilation succeed
+ // before the project is closed/re-opened.)
+ saveState(project);
+
+ return true;
+ }
- public abstract boolean compileFiles(BaseBuilder builder,
+ protected abstract void doCompileFiles(
+ List<IFile> filesToCompile, BaseBuilder builder,
IProject project, IAndroidTarget projectTarget,
- List<IPath> sourceFolders, IProgressMonitor monitor) throws CoreException;
+ List<IPath> sourceFolders, List<IFile> notCompiledOut, IProgressMonitor monitor)
+ throws CoreException;
+
+ protected abstract void doRemoveFiles(List<IFile> sources, IProgressMonitor monitor)
+ throws CoreException;
+
+ public final boolean loadState(IProject project) {
+ return ProjectHelper.loadBooleanProperty(project, getSavePropertyName(),
+ true /*defaultValue*/);
+ }
+
+ public final void saveState(IProject project) {
+ // TODO: Optimize by saving only the files that need compilation
+ ProjectHelper.saveStringProperty(project, getSavePropertyName(),
+ Boolean.toString(getToCompile().size() > 0));
+ }
+
+ protected abstract void loadOutputAndDependencies();
+
+ /**
+ * Goes through the build paths and fills the list of files to compile.
+ *
+ * @param project The project.
+ * @param sourceFolderPathList The list of source folder paths.
+ */
+ protected void buildSourceFileList() {
+ mFiles.clear();
+
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ List<IPath> sourceFolderPathList = BaseProjectHelper.getSourceClasspaths(mJavaProject);
+
+ for (IPath sourceFolderPath : sourceFolderPathList) {
+ IFolder sourceFolder = root.getFolder(sourceFolderPath);
+ // we don't look in the 'gen' source folder as there will be no source in there.
+ if (sourceFolder.exists() && sourceFolder.equals(getGenFolder()) == false) {
+ scanFolderForSourceFiles(sourceFolder, sourceFolder);
+ }
+ }
+ }
+
+ /**
+ * Scans a folder and fills the list of files to compile.
+ * @param sourceFolder the root source folder.
+ * @param folder The folder to scan.
+ */
+ private void scanFolderForSourceFiles(IFolder sourceFolder, IFolder folder) {
+ try {
+ IResource[] members = folder.members();
+ for (IResource r : members) {
+ // get the type of the resource
+ switch (r.getType()) {
+ case IResource.FILE:
+ // if this a file, check that the file actually exist
+ // and that it's the type of of file that's used in this generator
+ if (r.exists() &&
+ getExtension().equalsIgnoreCase(r.getFileExtension())) {
+ mFiles.put((IFile) r, new NonJavaFileBundle((IFile) r));
+ }
+ break;
+ case IResource.FOLDER:
+ // recursively go through children
+ scanFolderForSourceFiles(sourceFolder, (IFolder)r);
+ break;
+ default:
+ // this would mean it's a project or the workspace root
+ // which is unlikely to happen. we do nothing
+ break;
+ }
+ }
+ } catch (CoreException e) {
+ // Couldn't get the members list for some reason. Just return.
+ }
+ }
- public abstract void saveState(IProject project);
/**
* Merge the current list of source file to compile/remove with the one coming from the
* delta visitor
* @param visitor the delta visitor.
*/
- private void mergeFileModifications(JavaGeneratorDeltaVisitor visitor) {
- List<SourceData> toRemove = visitor.getFilesToRemove();
- List<SourceData> toCompile = visitor.getFilesToCompile();
+ private void mergeFileModifications(GeneratorDeltaVisitor visitor) {
+ Set<IFile> toRemove = visitor.getRemovedFiles();
+ Set<IFile> toCompile = visitor.getFilesToCompile();
// loop through the new toRemove list, and add it to the old one,
// plus remove any file that was still to compile and that are now
// removed
- for (SourceData r : toRemove) {
- if (mToRemove.indexOf(r) == -1) {
- mToRemove.add(r);
+ for (IFile r : toRemove) {
+ if (mRemoved.indexOf(r) == -1) {
+ mRemoved.add(r);
}
int index = mToCompile.indexOf(r);
@@ -286,14 +336,14 @@ public abstract class JavaGenerator {
// Also look for them in the remove list, this would mean that they
// were removed, then added back, and we shouldn't remove them, just
// recompile them.
- for (SourceData r : toCompile) {
+ for (IFile r : toCompile) {
if (mToCompile.indexOf(r) == -1) {
mToCompile.add(r);
}
- int index = mToRemove.indexOf(r);
+ int index = mRemoved.indexOf(r);
if (index != -1) {
- mToRemove.remove(index);
+ mRemoved.remove(index);
}
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/NonJavaFileBundle.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/NonJavaFileBundle.java
new file mode 100644
index 000000000..e75add06a
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/NonJavaFileBundle.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.internal.build;
+
+import org.eclipse.core.resources.IFile;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Data bundle for a given non-java source file. It contains a list of output files and a list
+ * of dependencies.
+ * The source file itself is a implied dependency and is not meant to be in the dependency list.
+ */
+public class NonJavaFileBundle {
+
+ private final IFile mSourceFile;
+ private final List<IFile> mOutputFiles = new ArrayList<IFile>();
+ private final List<IFile> mDependencyFiles = new ArrayList<IFile>();
+
+ public NonJavaFileBundle(IFile sourceFile) {
+ this(sourceFile, null, null);
+ }
+
+ public NonJavaFileBundle(IFile sourceFile,
+ List<IFile> outputFiles, List<IFile> dependencyFiles) {
+ mSourceFile = sourceFile;
+ if (outputFiles != null) {
+ mOutputFiles.addAll(outputFiles);
+ }
+ if (dependencyFiles != null) {
+ mDependencyFiles.addAll(dependencyFiles);
+ }
+ }
+
+ public NonJavaFileBundle(IFile sourceFile, IFile outputFile) {
+ mSourceFile = sourceFile;
+ if (outputFile != null) {
+ mOutputFiles.add(outputFile);
+ }
+ }
+
+ public IFile getSourceFile() {
+ return mSourceFile;
+ }
+
+ public boolean dependsOn(IFile file) {
+ return mDependencyFiles.contains(file);
+ }
+
+ public boolean generated(IFile file) {
+ return mOutputFiles.contains(file);
+ }
+
+ public void setOutputFiles(List<IFile> outputFiles) {
+ mOutputFiles.clear();
+ if (outputFiles != null) {
+ mOutputFiles.addAll(outputFiles);
+ }
+ }
+
+ public void setOutputFile(IFile outputFile) {
+ mOutputFiles.clear();
+ if (outputFile != null) {
+ mOutputFiles.add(outputFile);
+ }
+ }
+
+ /**
+ * Shortcut access to the first output file. This is useful for generator that only output
+ * one file.
+ */
+ public IFile getOutput() {
+ return mOutputFiles.get(0);
+ }
+
+ public List<IFile> getOutputFiles() {
+ return Collections.unmodifiableList(mOutputFiles);
+ }
+
+ @Override
+ public String toString() {
+ return "NonJavaFileBundle [mSourceFile=" + mSourceFile + ", mGeneratedFiles="
+ + mOutputFiles + ", mDependencies=" + mDependencyFiles + "]";
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java
index ee7756baf..2dacf0716 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java
@@ -38,8 +38,6 @@ import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IJavaProject;
import org.xml.sax.SAXException;
@@ -128,6 +126,10 @@ public abstract class BaseBuilder extends IncrementalProjectBuilder {
}
}
+ protected static class AbortBuildException extends Exception {
+ private static final long serialVersionUID = 1L;
+ }
+
public BaseBuilder() {
super();
mParserFactory = SAXParserFactory.newInstance();
@@ -304,58 +306,46 @@ public abstract class BaseBuilder extends IncrementalProjectBuilder {
* @param javaProject The {@link IJavaProject} being compiled.
* @throws CoreException
*/
- protected void abortOnBadSetup(IJavaProject javaProject) throws CoreException {
+ protected void abortOnBadSetup(IJavaProject javaProject) throws AbortBuildException {
IProject iProject = javaProject.getProject();
// check if we have finished loading the project target.
Sdk sdk = Sdk.getCurrent();
if (sdk == null) {
- // we exit silently
- stopBuild("SDK is not loaded yet");
+ throw new AbortBuildException();
}
// get the target for the project
IAndroidTarget target = sdk.getTarget(javaProject.getProject());
if (target == null) {
- // we exit silently
- stopBuild("Project target not resolved yet.");
+ throw new AbortBuildException();
}
// check on the target data.
if (sdk.checkAndLoadTargetData(target, javaProject) != LoadStatus.LOADED) {
- // we exit silently
- stopBuild("Project target not loaded yet.");
+ throw new AbortBuildException();
}
// abort if there are TARGET or ADT type markers
- IMarker[] markers = iProject.findMarkers(AndroidConstants.MARKER_TARGET,
- false /*includeSubtypes*/, IResource.DEPTH_ZERO);
-
- if (markers.length > 0) {
- stopBuild("");
- }
+ stopOnMarker(iProject, AndroidConstants.MARKER_TARGET, IResource.DEPTH_ZERO);
+ stopOnMarker(iProject, AndroidConstants.MARKER_ADT, IResource.DEPTH_ZERO);
+ }
- markers = iProject.findMarkers(AndroidConstants.MARKER_ADT, false /*includeSubtypes*/,
- IResource.DEPTH_ZERO);
+ protected void stopOnMarker(IProject project, String markerType, int depth)
+ throws AbortBuildException {
+ try {
+ IMarker[] markers = project.findMarkers(markerType, false /*includeSubtypes*/, depth);
- if (markers.length > 0) {
- stopBuild("");
+ if (markers.length > 0) {
+ throw new AbortBuildException();
+ }
+ } catch (CoreException e) {
+ // don't stop, something's really screwed up and the build will break later with
+ // a better error message.
}
}
/**
- * Throws an exception to cancel the build.
- *
- * @param error the error message
- * @param args the printf-style arguments to the error message.
- * @throws CoreException
- */
- protected final void stopBuild(String error, Object... args) throws CoreException {
- throw new CoreException(new Status(IStatus.CANCEL, AdtPlugin.PLUGIN_ID,
- String.format(error, args)));
- }
-
- /**
* Recursively delete all the derived resources from a root resource. The root resource is not
* deleted.
* @param rootResource the root resource
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java
index ac487390b..5df7f22c6 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java
@@ -22,10 +22,10 @@ import com.android.ide.eclipse.adt.AndroidPrintStream;
import com.android.ide.eclipse.adt.internal.build.AaptExecException;
import com.android.ide.eclipse.adt.internal.build.AaptParser;
import com.android.ide.eclipse.adt.internal.build.AaptResultException;
+import com.android.ide.eclipse.adt.internal.build.BuildHelper;
import com.android.ide.eclipse.adt.internal.build.DexException;
import com.android.ide.eclipse.adt.internal.build.Messages;
import com.android.ide.eclipse.adt.internal.build.NativeLibInJarException;
-import com.android.ide.eclipse.adt.internal.build.BuildHelper;
import com.android.ide.eclipse.adt.internal.build.BuildHelper.ResourceMarker;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
@@ -103,7 +103,7 @@ public class PostCompilerBuilder extends BaseBuilder {
private boolean mMakeFinalPackage;
private IPath mOutputFolder;
- private ArrayList<IPath> mSourceFolders;
+ private List<IPath> mSourceFolders;
private ReferencedProjectDeltaVisitor(IJavaProject javaProject) {
try {
@@ -224,9 +224,6 @@ public class PostCompilerBuilder extends BaseBuilder {
IJavaProject javaProject = JavaCore.create(project);
- // Top level check to make sure the build can move forward.
- abortOnBadSetup(javaProject);
-
// get the list of referenced projects.
List<IProject> javaProjects = ProjectHelper.getReferencedProjects(project);
List<IJavaProject> referencedJavaProjects = BuildHelper.getJavaProjects(
@@ -239,12 +236,15 @@ public class PostCompilerBuilder extends BaseBuilder {
refList.addAll(javaProjects);
allRefProjects = refList.toArray(new IProject[size]);
+ // Top level check to make sure the build can move forward.
+ abortOnBadSetup(javaProject);
+
// get the output folder, this method returns the path with a trailing
// separator
IFolder outputFolder = BaseProjectHelper.getOutputFolder(project);
// now we need to get the classpath list
- ArrayList<IPath> sourceList = BaseProjectHelper.getSourceClasspaths(javaProject);
+ List<IPath> sourceList = BaseProjectHelper.getSourceClasspaths(javaProject);
// First thing we do is go through the resource delta to not
// lose it if we have to abort the build for any reason.
@@ -596,6 +596,8 @@ public class PostCompilerBuilder extends BaseBuilder {
AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, getProject(),
"Build Success!");
}
+ } catch (AbortBuildException e) {
+ return allRefProjects;
} catch (Exception exception) {
// try to catch other exception to actually display an error. This will be useful
// if we get an NPE or something so that we can at least notify the user that something
@@ -634,17 +636,19 @@ public class PostCompilerBuilder extends BaseBuilder {
}
@Override
- protected void abortOnBadSetup(IJavaProject javaProject) throws CoreException {
+ protected void abortOnBadSetup(IJavaProject javaProject) throws AbortBuildException {
super.abortOnBadSetup(javaProject);
+ IProject iProject = getProject();
+
// for this version, we stop on any marker (ie also markers coming from JDT).
// The depth is set to ZERO to make sure we don't stop on warning on resources.
// Only markers set directly on the project are considered.
- IMarker[] markers = javaProject.getProject().findMarkers(null /*type*/,
- false /*includeSubtypes*/, IResource.DEPTH_ZERO);
+ stopOnMarker(iProject, null /*type*/, IResource.DEPTH_ZERO);
- if (markers.length > 0) {
- stopBuild("");
- }
+ // now search for other Precompiler type markers.
+ stopOnMarker(iProject, AndroidConstants.MARKER_AAPT_COMPILE, IResource.DEPTH_ZERO);
+ stopOnMarker(iProject, AndroidConstants.MARKER_AIDL, IResource.DEPTH_ZERO);
+ stopOnMarker(iProject, AndroidConstants.MARKER_ANDROID, IResource.DEPTH_ZERO);
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerDeltaVisitor.java
index eaa1722f6..7df8ef41a 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerDeltaVisitor.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerDeltaVisitor.java
@@ -29,7 +29,7 @@ import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
-import java.util.ArrayList;
+import java.util.List;
/**
* Delta resource visitor looking for changes that will trigger a new packaging of an Android
@@ -74,7 +74,7 @@ public class PostCompilerDeltaVisitor extends BaseDeltaVisitor
private boolean mMakeFinalPackage = false;
/** List of source folders. */
- private ArrayList<IPath> mSourceFolders;
+ private List<IPath> mSourceFolders;
private IPath mOutputPath;
@@ -91,7 +91,7 @@ public class PostCompilerDeltaVisitor extends BaseDeltaVisitor
* @param sourceFolders the list of source folders for the project, relative to the workspace.
* @param outputfolder the output folder of the project.
*/
- public PostCompilerDeltaVisitor(BaseBuilder builder, ArrayList<IPath> sourceFolders,
+ public PostCompilerDeltaVisitor(BaseBuilder builder, List<IPath> sourceFolders,
IFolder outputfolder) {
super(builder);
mSourceFolders = sourceFolders;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java
index 586dca55f..e58e96d10 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java
@@ -191,7 +191,7 @@ public class PreCompilerBuilder extends BaseBuilder {
// For the PreCompiler, only the library projects are considered Referenced projects,
// as only those projects have an impact on what is generated by this builder.
- List<IProject> libProjects = null;
+ IProject[] result = null;
try {
mDerivedProgressMonitor.reset();
@@ -207,7 +207,8 @@ public class PreCompilerBuilder extends BaseBuilder {
IAndroidTarget projectTarget = projectState.getTarget();
// get the libraries
- libProjects = projectState.getFullLibraryProjects();
+ List<IProject> libProjects = projectState.getFullLibraryProjects();
+ result = libProjects.toArray(new IProject[libProjects.size()]);
IJavaProject javaProject = JavaCore.create(project);
@@ -215,8 +216,7 @@ public class PreCompilerBuilder extends BaseBuilder {
abortOnBadSetup(javaProject);
// now we need to get the classpath list
- ArrayList<IPath> sourceFolderPathList = BaseProjectHelper.getSourceClasspaths(
- javaProject);
+ List<IPath> sourceFolderPathList = BaseProjectHelper.getSourceClasspaths(javaProject);
PreCompilerDeltaVisitor dv = null;
String javaPackage = null;
@@ -232,7 +232,7 @@ public class PreCompilerBuilder extends BaseBuilder {
mMustCompileResources = true;
for (JavaGenerator generator : mGeneratorList) {
- generator.prepareFullBuild(project, sourceFolderPathList);
+ generator.prepareFullBuild(project);
}
} else {
AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
@@ -247,7 +247,7 @@ public class PreCompilerBuilder extends BaseBuilder {
mMustCompileResources = true;
for (JavaGenerator generator : mGeneratorList) {
- generator.prepareFullBuild(project, sourceFolderPathList);
+ generator.prepareFullBuild(project);
}
} else {
dv = new PreCompilerDeltaVisitor(this, sourceFolderPathList, mGeneratorList);
@@ -256,7 +256,7 @@ public class PreCompilerBuilder extends BaseBuilder {
// record the state
mMustCompileResources |= dv.getCompileResources();
for (JavaGenerator generator : mGeneratorList) {
- generator.doneVisiting(project, sourceFolderPathList);
+ generator.doneVisiting(project);
}
// get the java package from the visitor
@@ -291,8 +291,7 @@ public class PreCompilerBuilder extends BaseBuilder {
if (dv != null && dv.mXmlError) {
AdtPlugin.printErrorToConsole(project, Messages.Xml_Error);
- // This interrupts the build. The next builders will not run.
- stopBuild(Messages.Xml_Error);
+ return result;
}
@@ -305,8 +304,7 @@ public class PreCompilerBuilder extends BaseBuilder {
AdtPlugin.printErrorToConsole(project, msg);
markProject(AndroidConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
- // This interrupts the build. The next builders will not run.
- stopBuild(msg);
+ return result;
// TODO: document whether code below that uses manifest (which is now guaranteed
// to be null) will actually be executed or not.
@@ -328,8 +326,7 @@ public class PreCompilerBuilder extends BaseBuilder {
SdkConstants.FN_ANDROID_MANIFEST_XML);
AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project, msg);
- // This interrupts the build. The next builders will not run.
- stopBuild(msg);
+ return result;
}
// Get the java package from the parser.
@@ -364,7 +361,7 @@ public class PreCompilerBuilder extends BaseBuilder {
AdtPlugin.printErrorToConsole(project, msg);
BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT,
msg, IMarker.SEVERITY_ERROR);
- stopBuild(msg);
+ return result;
} else if (minSdkValue < projectVersion.getApiLevel()) {
// integer minSdk is not high enough for the target => warning
String msg = String.format(
@@ -396,7 +393,7 @@ public class PreCompilerBuilder extends BaseBuilder {
AdtPlugin.printErrorToConsole(project, msg);
BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT,
msg, IMarker.SEVERITY_ERROR);
- stopBuild(msg);
+ return result;
} else if (codename.equals(minSdkVersion) == false) {
// platform and manifest codenames don't match => fatal error.
String msg = String.format(
@@ -405,7 +402,7 @@ public class PreCompilerBuilder extends BaseBuilder {
AdtPlugin.printErrorToConsole(project, msg);
BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT,
msg, IMarker.SEVERITY_ERROR);
- stopBuild(msg);
+ return result;
}
}
} else if (projectTarget.getVersion().isPreview()) {
@@ -418,7 +415,7 @@ public class PreCompilerBuilder extends BaseBuilder {
AdtPlugin.printErrorToConsole(project, msg);
BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT, msg,
IMarker.SEVERITY_ERROR);
- stopBuild(msg);
+ return result;
}
if (javaPackage == null || javaPackage.length() == 0) {
@@ -429,9 +426,7 @@ public class PreCompilerBuilder extends BaseBuilder {
BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT,
msg, IMarker.SEVERITY_ERROR);
- // This interrupts the build. The next builders will not run.
- // This also throws an exception and nothing beyond this line will run.
- stopBuild(msg);
+ return result;
} else if (javaPackage.indexOf('.') == -1) {
// The application package name does not contain 2+ segments!
String msg = String.format(
@@ -441,9 +436,7 @@ public class PreCompilerBuilder extends BaseBuilder {
BaseProjectHelper.markResource(manifestFile, AndroidConstants.MARKER_ADT,
msg, IMarker.SEVERITY_ERROR);
- // This interrupts the build. The next builders will not run.
- // This also throws an exception and nothing beyond this line will run.
- stopBuild(msg);
+ return result;
}
// at this point we have the java package. We need to make sure it's not a different
@@ -468,7 +461,7 @@ public class PreCompilerBuilder extends BaseBuilder {
doClean(project, monitor);
mMustCompileResources = true;
for (JavaGenerator generator : mGeneratorList) {
- generator.prepareFullBuild(project, sourceFolderPathList);
+ generator.prepareFullBuild(project);
}
saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES , mMustCompileResources);
@@ -489,13 +482,15 @@ public class PreCompilerBuilder extends BaseBuilder {
AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
Messages.Nothing_To_Compile);
}
+ } catch (AbortBuildException e) {
+ return result;
} finally {
// refresh the 'gen' source folder. Once this is done with the custom progress
// monitor to mark all new files as derived
mGenFolder.refreshLocal(IResource.DEPTH_INFINITE, mDerivedProgressMonitor);
}
- return libProjects.toArray(new IProject[libProjects.size()]);
+ return result;
}
@Override
@@ -556,9 +551,10 @@ public class PreCompilerBuilder extends BaseBuilder {
* @param manifest the {@link IFile} representing the project manifest
* @param libProjects the library dependencies
* @throws CoreException
+ * @throws AbortBuildException
*/
private void handleResources(IProject project, String javaPackage, IAndroidTarget projectTarget,
- IFile manifest, List<IProject> libProjects) throws CoreException {
+ IFile manifest, List<IProject> libProjects) throws CoreException, AbortBuildException {
// get the resource folder
IFolder resFolder = project.getFolder(AndroidConstants.WS_RESOURCES);
@@ -637,11 +633,11 @@ public class PreCompilerBuilder extends BaseBuilder {
* @param libResFolders the list of res folders for the library.
* @param customJavaPackage an optional javapackage to replace the main project java package.
* can be null.
- * @throws CoreException
+ * @throws AbortBuildException
*/
private void execAapt(IProject project, IAndroidTarget projectTarget, String osOutputPath,
String osResPath, String osManifestPath, IFolder packageFolder,
- ArrayList<IFolder> libResFolders, String customJavaPackage) throws CoreException {
+ ArrayList<IFolder> libResFolders, String customJavaPackage) throws AbortBuildException {
// We actually need to delete the manifest.java as it may become empty and
// in this case aapt doesn't generate an empty one, but instead doesn't
// touch it.
@@ -729,8 +725,7 @@ public class PreCompilerBuilder extends BaseBuilder {
Messages.AAPT_Error);
// abort if exec failed.
- // This interrupts the build. The next builders will not run.
- stopBuild(Messages.AAPT_Error);
+ throw new AbortBuildException();
}
} catch (IOException e1) {
// something happen while executing the process,
@@ -738,16 +733,16 @@ public class PreCompilerBuilder extends BaseBuilder {
String msg = String.format(Messages.AAPT_Exec_Error, array.get(0));
markProject(AndroidConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
- // This interrupts the build. The next builders will not run.
- stopBuild(msg);
+ // This interrupts the build.
+ throw new AbortBuildException();
} catch (InterruptedException e) {
// we got interrupted waiting for the process to end...
// mark the project and exit
String msg = String.format(Messages.AAPT_Exec_Error, array.get(0));
markProject(AndroidConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
- // This interrupts the build. The next builders will not run.
- stopBuild(msg);
+ // This interrupts the build.
+ throw new AbortBuildException();
}
// if the return code was OK, we refresh the folder that
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerDeltaVisitor.java
index ed3f5032b..25436ee94 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerDeltaVisitor.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerDeltaVisitor.java
@@ -18,9 +18,9 @@ package com.android.ide.eclipse.adt.internal.build.builders;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AndroidConstants;
+import com.android.ide.eclipse.adt.internal.build.GeneratorDeltaVisitor;
import com.android.ide.eclipse.adt.internal.build.JavaGenerator;
import com.android.ide.eclipse.adt.internal.build.Messages;
-import com.android.ide.eclipse.adt.internal.build.JavaGenerator.JavaGeneratorDeltaVisitor;
import com.android.ide.eclipse.adt.internal.build.builders.BaseBuilder.BaseDeltaVisitor;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
@@ -93,21 +93,20 @@ class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements
private List<IPath> mSourceFolders;
private boolean mIsGenSourceFolder = false;
- private final List<JavaGeneratorDeltaVisitor> mGeneratorDeltaVisitors =
- new ArrayList<JavaGeneratorDeltaVisitor>();
+ private final List<GeneratorDeltaVisitor> mGeneratorDeltaVisitors =
+ new ArrayList<GeneratorDeltaVisitor>();
private IWorkspaceRoot mRoot;
- public PreCompilerDeltaVisitor(BaseBuilder builder, ArrayList<IPath> sourceFolders,
+ public PreCompilerDeltaVisitor(BaseBuilder builder, List<IPath> sourceFolders,
List<JavaGenerator> generators) {
super(builder);
mSourceFolders = sourceFolders;
mRoot = ResourcesPlugin.getWorkspace().getRoot();
for (JavaGenerator generator : generators) {
- JavaGeneratorDeltaVisitor dv = generator.getDeltaVisitor();
- dv.setWorkspaceRoot(mRoot);
+ GeneratorDeltaVisitor dv = generator.getDeltaVisitor();
mGeneratorDeltaVisitors.add(dv);
}
}
@@ -277,11 +276,10 @@ class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements
} else {
// look to see if this java file was generated by a generator.
if (AndroidConstants.EXT_JAVA.equalsIgnoreCase(file.getFileExtension())) {
- for (JavaGeneratorDeltaVisitor dv : mGeneratorDeltaVisitors) {
- if (dv.handleChangedGeneratedJavaFile(
- mSourceFolder, file, mSourceFolders)) {
+ for (GeneratorDeltaVisitor dv : mGeneratorDeltaVisitors) {
+ if (dv.handleGeneratedFile(file, kind)) {
outputWarning = true;
- break; // there shouldn't be 2 generators that handles the same file.
+ break; // there shouldn't be 2 generators that handle the same file.
}
}
}
@@ -301,8 +299,8 @@ class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements
}
} else {
// this is another source folder.
- for (JavaGeneratorDeltaVisitor dv : mGeneratorDeltaVisitors) {
- dv.handleChangedNonJavaFile(mSourceFolder, file, kind);
+ for (GeneratorDeltaVisitor dv : mGeneratorDeltaVisitors) {
+ dv.handleSourceFile(file, kind);
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ResourceManagerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ResourceManagerBuilder.java
index 84e2751e4..7d76ea1fa 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ResourceManagerBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ResourceManagerBuilder.java
@@ -41,7 +41,7 @@ import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
-import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
/**
@@ -81,7 +81,11 @@ public class ResourceManagerBuilder extends BaseBuilder {
// check for existing target marker, in which case we abort.
// (this means: no SDK, no target, or unresolvable target.)
- abortOnBadSetup(javaProject);
+ try {
+ abortOnBadSetup(javaProject);
+ } catch (AbortBuildException e) {
+ return null;
+ }
// Check the compiler compliance level, displaying the error message
// since this is the first builder.
@@ -103,8 +107,7 @@ public class ResourceManagerBuilder extends BaseBuilder {
markProject(AndroidConstants.MARKER_ADT, errorMessage, IMarker.SEVERITY_ERROR);
AdtPlugin.printErrorToConsole(project, errorMessage);
- // interrupt the build. The next builders will not run.
- stopBuild(errorMessage);
+ return null;
}
// Check that the SDK directory has been setup.
@@ -115,16 +118,14 @@ public class ResourceManagerBuilder extends BaseBuilder {
markProject(AndroidConstants.MARKER_ADT, Messages.No_SDK_Setup_Error,
IMarker.SEVERITY_ERROR);
- // This interrupts the build. The next builders will not run.
- stopBuild(Messages.No_SDK_Setup_Error);
+ return null;
}
// check the project has a target
IAndroidTarget projectTarget = Sdk.getCurrent().getTarget(project);
if (projectTarget == null) {
// no target. marker has been set by the container initializer: exit silently.
- // This interrupts the build. The next builders will not run.
- stopBuild("Project has no target");
+ return null;
}
// check the 'gen' source folder is present
@@ -167,15 +168,14 @@ public class ResourceManagerBuilder extends BaseBuilder {
AdtPlugin.printErrorToConsole(project, message);
markProject(AndroidConstants.MARKER_ADT, message, IMarker.SEVERITY_ERROR);
- // This interrupts the build. The next builders will not run.
- stopBuild(message);
+ return null;
} else if (hasGenSrcFolder == false || genFolderPresent == false) {
// either there is no 'gen' source folder in the project (older SDK),
// or the folder does not exist (was deleted, or was a fresh svn checkout maybe.)
// In case we are migrating from an older SDK, we go through the current source
// folders and delete the generated Java files.
- ArrayList<IPath> sourceFolders = BaseProjectHelper.getSourceClasspaths(javaProject);
+ List<IPath> sourceFolders = BaseProjectHelper.getSourceClasspaths(javaProject);
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
for (IPath path : sourceFolders) {
IResource member = root.findMember(path);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java
index 49a44d699..6485f9657 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java
@@ -53,6 +53,7 @@ import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import java.util.ArrayList;
+import java.util.List;
/**
* Utility methods to manipulate projects.
@@ -73,7 +74,7 @@ public final class BaseProjectHelper {
* @param javaProject
* @return a list of path relative to the workspace root.
*/
- public static ArrayList<IPath> getSourceClasspaths(IJavaProject javaProject) {
+ public static List<IPath> getSourceClasspaths(IJavaProject javaProject) {
ArrayList<IPath> sourceList = new ArrayList<IPath>();
IClasspathEntry[] classpaths = javaProject.readRawClasspath();
if (classpaths != null) {
@@ -91,7 +92,7 @@ public final class BaseProjectHelper {
* @param project
* @return a list of path relative to the workspace root.
*/
- public static ArrayList<IPath> getSourceClasspaths(IProject project) {
+ public static List<IPath> getSourceClasspaths(IProject project) {
IJavaProject javaProject = JavaCore.create(project);
return getSourceClasspaths(javaProject);
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
index a7e86474b..5d925db43 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
@@ -1394,8 +1394,7 @@ public final class Sdk {
final String varName = getLibraryVariableName(libName);
// get the list of source folders for the library.
- ArrayList<IPath> sourceFolderPaths = BaseProjectHelper.getSourceClasspaths(
- library);
+ List<IPath> sourceFolderPaths = BaseProjectHelper.getSourceClasspaths(library);
// loop on all the source folder, ignoring FD_GEN and add them
// as linked folder