From fdb4570e8d2c47b5515d1ae57a8b6c4cb94ca26d Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Mon, 23 Apr 2012 17:07:36 +0400 Subject: [PATCH] IDEA-83336 support BuildConfig.java generating [rev=nnmatveev] --- .../android/util/AndroidCommonUtils.java | 8 +- plugins/android/src/META-INF/plugin.xml | 1 + .../android/compiler/AndroidAptCompiler.java | 20 +- .../compiler/AndroidAutogenerator.java | 89 ++++++++ .../compiler/AndroidAutogeneratorMode.java | 2 +- .../AndroidBuildConfigGeneratingCompiler.java | 193 ++++++++++++++++++ .../android/compiler/AndroidCompileUtil.java | 18 ++ .../compiler/AndroidPrecompileTask.java | 5 + .../jetbrains/android/facet/AndroidFacet.java | 1 + .../facet/AndroidResourceFilesListener.java | 66 +++--- .../android/facet/AndroidRootUtil.java | 21 +- 11 files changed, 372 insertions(+), 52 deletions(-) create mode 100644 plugins/android/src/org/jetbrains/android/compiler/AndroidBuildConfigGeneratingCompiler.java diff --git a/plugins/android/common/src/org/jetbrains/android/util/AndroidCommonUtils.java b/plugins/android/common/src/org/jetbrains/android/util/AndroidCommonUtils.java index f52243482aa3..b1ebfaf600bd 100644 --- a/plugins/android/common/src/org/jetbrains/android/util/AndroidCommonUtils.java +++ b/plugins/android/common/src/org/jetbrains/android/util/AndroidCommonUtils.java @@ -53,8 +53,9 @@ public class AndroidCommonUtils { private static final Pattern ERROR_PATTERN = Pattern.compile(".*error.*"); private static final Pattern EXCEPTION_PATTERN = Pattern.compile(".*exception.*"); - private static Pattern R_PATTERN = Pattern.compile("R(\\$.*)?\\.class"); - private static Pattern MANIFEST_PATTERN = Pattern.compile("Manifest(\\$.*)?\\.class"); + private static final Pattern R_PATTERN = Pattern.compile("R(\\$.*)?\\.class"); + private static final Pattern MANIFEST_PATTERN = Pattern.compile("Manifest(\\$.*)?\\.class"); + private static final String BUILD_CONFIG_CLASS_NAME = "BuildConfig.class"; public static final Pattern COMPILER_MESSAGE_PATTERN = Pattern.compile("(.+):(\\d+):.+"); @@ -226,7 +227,8 @@ public class AndroidCommonUtils { if (!packRAndManifestClasses && (R_PATTERN.matcher(file.getName()).matches() || - MANIFEST_PATTERN.matcher(file.getName()).matches())) { + MANIFEST_PATTERN.matcher(file.getName()).matches() || + BUILD_CONFIG_CLASS_NAME.equals(file.getName()))) { return; } diff --git a/plugins/android/src/META-INF/plugin.xml b/plugins/android/src/META-INF/plugin.xml index 8787c3bc246b..e247452399f6 100644 --- a/plugins/android/src/META-INF/plugin.xml +++ b/plugins/android/src/META-INF/plugin.xml @@ -134,6 +134,7 @@ + diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidAptCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidAptCompiler.java index 6349f4880e33..ac03235e23f0 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidAptCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidAptCompiler.java @@ -26,8 +26,6 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.ArrayUtil; -import com.intellij.util.containers.HashSet; import org.jetbrains.android.compiler.tools.AndroidApt; import org.jetbrains.android.dom.manifest.Manifest; import org.jetbrains.android.facet.AndroidFacet; @@ -260,7 +258,7 @@ public class AndroidAptCompiler implements SourceGeneratingCompiler { -1, -1); continue; } - final String[] libPackages = getLibPackages(module, packageName); + final String[] libPackages = AndroidCompileUtil.getLibPackages(module, packageName); final Module circularDepLibWithSamePackage = AndroidCompileUtil.findCircularDependencyOnLibraryWithSamePackage(facet); if (circularDepLibWithSamePackage != null && !facet.getConfiguration().LIBRARY_PROJECT) { @@ -304,22 +302,6 @@ public class AndroidAptCompiler implements SourceGeneratingCompiler { } return false; } - - @NotNull - private static String[] getLibPackages(@NotNull Module module, @NotNull String packageName) { - final Set packageSet = new HashSet(); - packageSet.add(packageName); - - final List result = new ArrayList(); - - for (String libPackage : AndroidUtils.getDepLibsPackages(module)) { - if (packageSet.add(libPackage)) { - result.add(libPackage); - } - } - - return ArrayUtil.toStringArray(result); - } } private static class MyValidityState extends ResourceNamesValidityState { diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java index c5d4f05b6c48..f79e8f4eea96 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogenerator.java @@ -2,6 +2,7 @@ package org.jetbrains.android.compiler; import com.android.AndroidConstants; import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.internal.build.BuildConfigGenerator; import com.intellij.compiler.impl.CompilerUtil; import com.intellij.compiler.impl.ModuleCompileScope; import com.intellij.openapi.application.ApplicationManager; @@ -58,6 +59,7 @@ public class AndroidAutogenerator { case AIDL: return facet.getConfiguration().REGENERATE_JAVA_BY_AIDL; case RENDERSCRIPT: + case BUILDCONFIG: return true; default: LOG.error("Unknown autogenerator mode " + mode); @@ -81,6 +83,9 @@ public class AndroidAutogenerator { case RENDERSCRIPT: runRenderscript(facet, context); break; + case BUILDCONFIG: + runBuildConfigGenerator(facet, context); + break; default: LOG.error("Unknown mode" + mode); } @@ -96,6 +101,80 @@ public class AndroidAutogenerator { } } + private static void runBuildConfigGenerator(@NotNull final AndroidFacet facet, @NotNull final CompileContext context) { + final Module module = facet.getModule(); + + final BuildconfigAutogenerationItem item = ApplicationManager.getApplication().runReadAction( + new Computable() { + @Nullable + @Override + public BuildconfigAutogenerationItem compute() { + if (module.isDisposed() || module.getProject().isDisposed()) { + return null; + } + + final String sourceRootPath = AndroidRootUtil.getBuildconfigGenSourceRootPath(facet); + if (sourceRootPath == null) { + return null; + } + + final VirtualFile manifestFile = AndroidRootUtil.getManifestFileForCompiler(facet); + if (manifestFile == null) { + context.addMessage(CompilerMessageCategory.ERROR, AndroidBundle.message("android.compilation.error.manifest.not.found"), + null, -1, -1); + return null; + } + + final Manifest manifest = AndroidUtils.loadDomElement(module, manifestFile, Manifest.class); + if (manifest == null) { + context.addMessage(CompilerMessageCategory.ERROR, "Cannot parse file", manifestFile.getUrl(), -1, -1); + return null; + } + + String packageName = manifest.getPackage().getValue(); + if (packageName != null) { + packageName = packageName.trim(); + } + + if (packageName == null || packageName.length() <= 0) { + context.addMessage(CompilerMessageCategory.ERROR, AndroidBundle.message("package.not.found.error"), manifestFile.getUrl(), + -1, -1); + return null; + } + return new BuildconfigAutogenerationItem(packageName, FileUtil.toSystemDependentName(sourceRootPath)); + } + }); + + // doesn't matter, because autogenerated class is used for resolve/completion only + final boolean debug = true; + final BuildConfigGenerator generator = new BuildConfigGenerator(item.mySourceRootOsPath, item.myPackage, debug); + try { + generator.generate(); + + final VirtualFile genSourceRoot = LocalFileSystem.getInstance().findFileByPath(item.mySourceRootOsPath); + if (genSourceRoot != null) { + genSourceRoot.refresh(false, true); + } + facet.clearAutogeneratedFiles(AndroidAutogeneratorMode.BUILDCONFIG); + + final VirtualFile genFile = LocalFileSystem.getInstance().findFileByPath( + item.mySourceRootOsPath + '/' + item.myPackage.replace('.', '/') + '/' + BuildConfigGenerator.BUILD_CONFIG_NAME); + + if (genFile != null && genFile.exists()) { + facet.markFileAutogenerated(AndroidAutogeneratorMode.BUILDCONFIG, genFile); + } + } + catch (final IOException e) { + LOG.info(e); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + if (module.getProject().isDisposed()) return; + context.addMessage(CompilerMessageCategory.ERROR, "I/O error: " + e.getMessage(), null, -1, -1); + } + }); + } + } + private static void runAapt(@NotNull final AndroidFacet facet, @NotNull final CompileContext context) { final Module module = facet.getModule(); @@ -644,4 +723,14 @@ public class AndroidAutogenerator { myRawDirPath = rawDirPath; } } + + private static class BuildconfigAutogenerationItem { + final String myPackage; + final String mySourceRootOsPath; + + private BuildconfigAutogenerationItem(@NotNull String aPackage, @NotNull String sourceRootOsPath) { + myPackage = aPackage; + mySourceRootOsPath = sourceRootOsPath; + } + } } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogeneratorMode.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogeneratorMode.java index 7b8852e674a0..1d685045a55e 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogeneratorMode.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidAutogeneratorMode.java @@ -4,5 +4,5 @@ package org.jetbrains.android.compiler; * @author Eugene.Kudelevsky */ public enum AndroidAutogeneratorMode { - AAPT, AIDL, RENDERSCRIPT + AAPT, AIDL, RENDERSCRIPT, BUILDCONFIG } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidBuildConfigGeneratingCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidBuildConfigGeneratingCompiler.java new file mode 100644 index 000000000000..f0f199ffe6ec --- /dev/null +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidBuildConfigGeneratingCompiler.java @@ -0,0 +1,193 @@ +package org.jetbrains.android.compiler; + +import com.android.sdklib.internal.build.BuildConfigGenerator; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.compiler.*; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.android.dom.manifest.Manifest; +import org.jetbrains.android.facet.AndroidFacet; +import org.jetbrains.android.facet.AndroidRootUtil; +import org.jetbrains.android.util.AndroidBundle; +import org.jetbrains.android.util.AndroidUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Eugene.Kudelevsky + */ +public class AndroidBuildConfigGeneratingCompiler implements SourceGeneratingCompiler { + private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.compiler.AndroidBuildConfigGeneratingCompiler"); + + @Nullable + @Override + public VirtualFile getPresentableFile(CompileContext context, Module module, VirtualFile outputRoot, VirtualFile generatedFile) { + return null; + } + + @Override + public GenerationItem[] getGenerationItems(final CompileContext context) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public GenerationItem[] compute() { + final List result = new ArrayList(); + + for (Module module : ModuleManager.getInstance(context.getProject()).getModules()) { + final AndroidFacet facet = AndroidFacet.getInstance(module); + if (facet == null) { + continue; + } + + final VirtualFile manifestFile = AndroidRootUtil.getManifestFileForCompiler(facet); + if (manifestFile == null) { + context.addMessage(CompilerMessageCategory.ERROR, AndroidBundle.message("android.compilation.error.manifest.not.found"), + null, -1, -1); + continue; + } + + final Manifest manifest = AndroidUtils.loadDomElement(module, manifestFile, Manifest.class); + if (manifest == null) { + context.addMessage(CompilerMessageCategory.ERROR, "Cannot parse file", manifestFile.getUrl(), -1, -1); + continue; + } + + String packageName = manifest.getPackage().getValue(); + if (packageName != null) { + packageName = packageName.trim(); + } + if (packageName == null || packageName.length() <= 0) { + context.addMessage(CompilerMessageCategory.ERROR, AndroidBundle.message("package.not.found.error"), manifestFile.getUrl(), + -1, -1); + continue; + } + final boolean debug = !AndroidCompileUtil.isReleaseBuild(context); + result.add(new MyGenerationItem(module, packageName, debug)); + + for (String libPackage : AndroidCompileUtil.getLibPackages(module, packageName)) { + result.add(new MyGenerationItem(module, libPackage, debug)); + } + } + return result.toArray(new GenerationItem[result.size()]); + } + }); + } + + @Override + public GenerationItem[] generate(CompileContext context, + GenerationItem[] items, + VirtualFile outputRootDirectory) { + if (items == null || items.length == 0) { + return new GenerationItem[0]; + } + context.getProgressIndicator().setText("Generating BuildConfig.java..."); + + final String genFolderOsPath = FileUtil.toSystemDependentName(outputRootDirectory.getPath()); + final List result = new ArrayList(); + + for (GenerationItem item : items) { + final MyGenerationItem genItem = (MyGenerationItem)item; + final BuildConfigGenerator generator = new BuildConfigGenerator(genFolderOsPath, genItem.myPackage, genItem.myDebug); + try { + generator.generate(); + result.add(genItem); + } + catch (IOException e) { + context.addMessage(CompilerMessageCategory.ERROR, "I/O error: " + e.getMessage(), null, -1, -1); + LOG.info(e); + } + } + + if (result.size() > 0) { + outputRootDirectory.refresh(false, true); + } + return result.toArray(new GenerationItem[result.size()]); + } + + @NotNull + @Override + public String getDescription() { + return "Android BuildConfig Generator"; + } + + @Override + public boolean validateConfiguration(CompileScope scope) { + return true; + } + + @Override + public ValidityState createValidityState(DataInput in) throws IOException { + return new MyValidityState(in); + } + + private static class MyGenerationItem implements GenerationItem{ + final Module myModule; + final String myPackage; + final boolean myDebug; + + private MyGenerationItem(@NotNull Module module, @NotNull String aPackage, boolean debug) { + myModule = module; + myPackage = aPackage; + myDebug = debug; + } + + @Override + public String getPath() { + return myPackage.replace('.', '/') + '/' + BuildConfigGenerator.BUILD_CONFIG_NAME; + } + + @Override + public ValidityState getValidityState() { + return new MyValidityState(myPackage, myDebug); + } + + @Override + public Module getModule() { + return myModule; + } + + @Override + public boolean isTestSource() { + return false; + } + } + + private static class MyValidityState implements ValidityState { + private final String myPackage; + private boolean myDebug; + + private MyValidityState(DataInput in) throws IOException { + myPackage = in.readUTF(); + myDebug = in.readBoolean(); + } + + private MyValidityState(@NotNull String aPackage, boolean debug) { + myPackage = aPackage; + myDebug = debug; + } + + @Override + public boolean equalsTo(ValidityState otherState) { + if (!(otherState instanceof MyValidityState)) { + return false; + } + final MyValidityState otherState1 = (MyValidityState)otherState; + return otherState1.myPackage.equals(myPackage) && otherState1.myDebug == myDebug; + } + + @Override + public void save(DataOutput out) throws IOException { + out.writeUTF(myPackage); + out.writeBoolean(myDebug); + } + } +} diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java index 53041f9739b3..c681b3dd4a60 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java @@ -654,6 +654,8 @@ public class AndroidCompileUtil { final Module module = facet.getModule(); final GlobalSearchScope moduleScope = facet.getModule().getModuleScope(); + initializeGenSourceRoot(module, AndroidRootUtil.getBuildconfigGenSourceRootPath(facet), true, true); + initializeGenSourceRoot(module, AndroidRootUtil.getRenderscriptGenSourceRootPath(facet), FileTypeIndex.getFiles(AndroidRenderscriptFileType.INSTANCE, moduleScope).size() > 0, true); @@ -900,4 +902,20 @@ public class AndroidCompileUtil { } return null; } + + @NotNull + public static String[] getLibPackages(@NotNull Module module, @NotNull String packageName) { + final Set packageSet = new HashSet(); + packageSet.add(packageName); + + final List result = new ArrayList(); + + for (String libPackage : AndroidUtils.getDepLibsPackages(module)) { + if (packageSet.add(libPackage)) { + result.add(libPackage); + } + } + + return ArrayUtil.toStringArray(result); + } } \ No newline at end of file diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidPrecompileTask.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidPrecompileTask.java index 577d46b4d98b..7539aa2329a4 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidPrecompileTask.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidPrecompileTask.java @@ -190,6 +190,11 @@ public class AndroidPrecompileTask implements CompileTask { sourceRootSet.remove(rsGenRoot); } + final VirtualFile buildconfigGenDir = AndroidRootUtil.getBuildconfigGenDir(facet); + if (buildconfigGenDir != null) { + sourceRootSet.remove(buildconfigGenDir); + } + final ExcludeEntryDescription[] descriptions = configuration.getExcludeEntryDescriptions(); configuration.removeAllExcludeEntryDescriptions(); diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java index 3642a15280e7..b16659b7212b 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java @@ -459,6 +459,7 @@ public class AndroidFacet extends Facet { AndroidCompileUtil.generate(module, AndroidAutogeneratorMode.AIDL); } AndroidCompileUtil.generate(module, AndroidAutogeneratorMode.RENDERSCRIPT); + AndroidCompileUtil.generate(module, AndroidAutogeneratorMode.BUILDCONFIG); activateSourceAutogenerating(); } diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java b/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java index 733a27394c50..6a67ea9fac2e 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java @@ -39,6 +39,9 @@ import org.jetbrains.android.util.ResourceEntry; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Set; import static org.jetbrains.android.util.AndroidUtils.findSourceRoot; @@ -144,59 +147,61 @@ class AndroidResourceFilesListener extends VirtualFileAdapter { return; } - final AndroidAutogeneratorMode autogenerationMode = - ApplicationManager.getApplication().runReadAction(new Computable() { + final List autogenerationModes = + ApplicationManager.getApplication().runReadAction(new Computable>() { @Nullable - public AndroidAutogeneratorMode compute() { - return computeCompilerToRunAndInvalidateLocalAttributesMap(); + public List compute() { + return computeCompilersToRunAndInvalidateLocalAttributesMap(); } }); - if (autogenerationMode == null) { + if (autogenerationModes.isEmpty()) { return; } - if (autogenerationMode == AndroidAutogeneratorMode.AAPT && - AndroidRootUtil.getManifestFile(myFacet) != myEvent.getFile()) { + for (AndroidAutogeneratorMode autogenerationMode : autogenerationModes) { + if (autogenerationMode == AndroidAutogeneratorMode.AAPT && + AndroidRootUtil.getManifestFile(myFacet) != myEvent.getFile()) { - final HashSet resourceSet = new HashSet(); + final HashSet resourceSet = new HashSet(); - DumbService.getInstance(myFacet.getModule().getProject()).waitForSmartMode(); + DumbService.getInstance(myFacet.getModule().getProject()).waitForSmartMode(); - AndroidCompileUtil.collectAllResources(myFacet, resourceSet); + AndroidCompileUtil.collectAllResources(myFacet, resourceSet); - synchronized (RESOURCES_SET_LOCK) { - if (resourceSet.equals(myResourceSet) && - !myFacet.areSourcesGeneratedWithErrors(AndroidAutogeneratorMode.AAPT)) { - return; + synchronized (RESOURCES_SET_LOCK) { + if (resourceSet.equals(myResourceSet) && + !myFacet.areSourcesGeneratedWithErrors(AndroidAutogeneratorMode.AAPT)) { + return; + } + myResourceSet = resourceSet; } - myResourceSet = resourceSet; } + AndroidCompileUtil.generate(myFacet.getModule(), autogenerationMode, true); } - AndroidCompileUtil.generate(myFacet.getModule(), autogenerationMode, true); } - @Nullable - private AndroidAutogeneratorMode computeCompilerToRunAndInvalidateLocalAttributesMap() { + @NotNull + private List computeCompilersToRunAndInvalidateLocalAttributesMap() { if (myFacet.isDisposed()) { - return null; + return Collections.emptyList(); } final Module myModule = myFacet.getModule(); final Project project = myModule.getProject(); if (project.isDisposed()) { - return null; + return Collections.emptyList(); } final VirtualFile file = myEvent.getFile(); final Module module = ModuleUtil.findModuleForFile(file, project); if (module != myModule) { - return null; + return Collections.emptyList(); } VirtualFile parent = myEvent.getParent(); if (parent == null) { - return null; + return Collections.emptyList(); } final VirtualFile gp = parent.getParent(); @@ -207,10 +212,13 @@ class AndroidResourceFilesListener extends VirtualFileAdapter { ResourceFolderType.VALUES.getName().equals(AndroidCommonUtils.getResourceTypeByDirName(parent.getName()))) { myFacet.getLocalResourceManager().invalidateAttributeDefinitions(); } + final VirtualFile manifestFile = AndroidRootUtil.getManifestFile(myFacet); + + final List modes = new ArrayList(); if (AndroidAptCompiler.isToCompileModule(module, myFacet.getConfiguration()) && (myFacet.getConfiguration().REGENERATE_R_JAVA && (gp == resourceDir || - AndroidRootUtil.getManifestFile(myFacet) == file))) { + manifestFile == file))) { final Manifest manifest = myFacet.getManifest(); final String aPackage = manifest != null ? manifest.getPackage().getValue() : null; @@ -219,23 +227,27 @@ class AndroidResourceFilesListener extends VirtualFileAdapter { AndroidCompileUtil.removeDuplicatingClasses(myModule, myCachedPackage, AndroidUtils.R_CLASS_NAME, null, aptGenDirPath); } myCachedPackage = aPackage; - return AndroidAutogeneratorMode.AAPT; + modes.add(AndroidAutogeneratorMode.AAPT); } if (myFacet.getConfiguration().REGENERATE_JAVA_BY_AIDL && file.getFileType() == AndroidIdlFileType.ourFileType) { VirtualFile sourceRoot = findSourceRoot(myModule, file); if (sourceRoot != null && AndroidRootUtil.getAidlGenDir(myFacet) != sourceRoot) { - return AndroidAutogeneratorMode.AIDL; + modes.add(AndroidAutogeneratorMode.AIDL); } } if (file.getFileType() == AndroidRenderscriptFileType.INSTANCE) { final VirtualFile sourceRoot = findSourceRoot(myModule, file); if (sourceRoot != null && AndroidRootUtil.getRenderscriptGenDir(myFacet) != sourceRoot) { - return AndroidAutogeneratorMode.RENDERSCRIPT; + modes.add(AndroidAutogeneratorMode.RENDERSCRIPT); } } - return null; + + if (manifestFile == file) { + modes.add(AndroidAutogeneratorMode.BUILDCONFIG); + } + return modes; } @Override diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java b/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java index e88bdb910992..b46650cfb0f6 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java @@ -178,6 +178,12 @@ public class AndroidRootUtil { return path != null ? LocalFileSystem.getInstance().findFileByPath(path) : null; } + @Nullable + public static VirtualFile getBuildconfigGenDir(@NotNull AndroidFacet facet) { + final String path = getBuildconfigGenSourceRootPath(facet); + return path != null ? LocalFileSystem.getInstance().findFileByPath(path) : null; + } + // works even if there is no Android facet in a module @Nullable @@ -355,14 +361,25 @@ public class AndroidRootUtil { @Nullable public static String getRenderscriptGenSourceRootPath(@NotNull AndroidFacet facet) { - // todo: return correct path for mavenized module + // todo: return correct path for mavenized module when it'll be supported + return getDefaultGenSourceRoot(facet); + } + + @Nullable + public static String getBuildconfigGenSourceRootPath(@NotNull AndroidFacet facet) { + // todo: return correct path for mavenized module when it'll be supported + return getDefaultGenSourceRoot(facet); + } + + @Nullable + private static String getDefaultGenSourceRoot(AndroidFacet facet) { final VirtualFile mainContentRoot = getMainContentRoot(facet); final String moduleDirPath = mainContentRoot != null ? mainContentRoot.getPath() : null; return moduleDirPath != null ? moduleDirPath + '/' + SdkConstants.FD_GEN_SOURCES : null; } - + @Nullable public static VirtualFile getMainContentRoot(@NotNull AndroidFacet facet) { final Module module = facet.getModule();