| /* |
| * Copyright (C) 2012 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 |
| * |
| * 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.build.gradle.internal.dsl; |
| |
| import com.android.annotations.NonNull; |
| import com.android.annotations.Nullable; |
| import com.android.build.gradle.api.JavaCompileOptions; |
| import com.android.build.gradle.internal.errors.DeprecationReporter; |
| import com.android.build.gradle.internal.scope.CodeShrinker; |
| import com.android.builder.core.BuilderConstants; |
| import com.android.builder.core.DefaultBuildType; |
| import com.android.builder.errors.EvalIssueReporter; |
| import com.android.builder.errors.EvalIssueReporter.Type; |
| import com.android.builder.internal.ClassFieldImpl; |
| import com.android.builder.model.BaseConfig; |
| import com.android.builder.model.ClassField; |
| import com.google.common.annotations.VisibleForTesting; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.Iterables; |
| import java.io.Serializable; |
| import java.util.List; |
| import java.util.function.Supplier; |
| import javax.inject.Inject; |
| import org.gradle.api.Action; |
| import org.gradle.api.Incubating; |
| import org.gradle.api.Project; |
| import org.gradle.api.model.ObjectFactory; |
| import org.gradle.api.provider.Property; |
| import org.gradle.api.tasks.Internal; |
| |
| /** DSL object to configure build types. */ |
| @SuppressWarnings({"unused", "WeakerAccess", "UnusedReturnValue", "Convert2Lambda"}) |
| public class BuildType extends DefaultBuildType implements CoreBuildType, Serializable { |
| |
| private static final long serialVersionUID = 1L; |
| |
| /** |
| * Whether the current thread should check that the both the old and new way of configuring |
| * bytecode postProcessing are not used at the same time. |
| * |
| * <p>The checks are disabled during {@link #initWith(com.android.builder.model.BuildType)}. |
| */ |
| private static ThreadLocal<Boolean> dslChecksEnabled = |
| ThreadLocal.withInitial( |
| new Supplier<Boolean>() { |
| @Override |
| public Boolean get() { |
| return true; |
| } |
| }); |
| |
| /** |
| * Describes how code postProcessing is configured. We don't allow mixing the old and new DSLs. |
| */ |
| public enum PostProcessingConfiguration { |
| POSTPROCESSING_BLOCK, |
| OLD_DSL, |
| } |
| |
| @NonNull private final Project project; |
| @NonNull private final NdkOptions ndkConfig; |
| @NonNull private final ExternalNativeBuildOptions externalNativeBuildOptions; |
| @NonNull |
| private final com.android.build.gradle.internal.dsl.JavaCompileOptions javaCompileOptions; |
| @NonNull private final ShaderOptions shaderOptions; |
| @NonNull private final EvalIssueReporter issueReporter; |
| @NonNull private final DeprecationReporter deprecationReporter; |
| @NonNull private final PostProcessingBlock postProcessingBlock; |
| |
| @Nullable private PostProcessingConfiguration postProcessingConfiguration; |
| @Nullable private String postProcessingDslMethodUsed; |
| |
| private boolean shrinkResources = false; |
| private Boolean useProguard = false; |
| private Boolean crunchPngs; |
| private boolean isCrunchPngsDefault = true; |
| private final Property<Boolean> isDefault; |
| |
| @Inject |
| public BuildType( |
| @NonNull String name, |
| @NonNull Project project, |
| @NonNull ObjectFactory objectFactory, |
| @NonNull EvalIssueReporter issueReporter, |
| @NonNull DeprecationReporter deprecationReporter) { |
| super(name); |
| this.project = project; |
| this.issueReporter = issueReporter; |
| this.deprecationReporter = deprecationReporter; |
| |
| javaCompileOptions = |
| objectFactory.newInstance( |
| com.android.build.gradle.internal.dsl.JavaCompileOptions.class, |
| objectFactory); |
| shaderOptions = objectFactory.newInstance(ShaderOptions.class); |
| ndkConfig = objectFactory.newInstance(NdkOptions.class); |
| externalNativeBuildOptions = |
| objectFactory.newInstance(ExternalNativeBuildOptions.class, objectFactory); |
| postProcessingBlock = objectFactory.newInstance(PostProcessingBlock.class, project); |
| isDefault = objectFactory.property(Boolean.class).convention(false); |
| } |
| |
| @VisibleForTesting |
| BuildType( |
| @NonNull String name, |
| @NonNull Project project, |
| @NonNull EvalIssueReporter issueReporter, |
| @NonNull DeprecationReporter deprecationReporter) { |
| |
| super(name); |
| this.project = project; |
| this.issueReporter = issueReporter; |
| this.deprecationReporter = deprecationReporter; |
| javaCompileOptions = new com.android.build.gradle.internal.dsl.JavaCompileOptions(); |
| shaderOptions = new ShaderOptions(); |
| ndkConfig = new NdkOptions(); |
| externalNativeBuildOptions = new ExternalNativeBuildOptions(); |
| postProcessingBlock = new PostProcessingBlock(project); |
| isDefault = project.getObjects().property(Boolean.class).convention(false); |
| } |
| |
| private ImmutableList<String> matchingFallbacks; |
| |
| public void setMatchingFallbacks(String... fallbacks) { |
| this.matchingFallbacks = ImmutableList.copyOf(fallbacks); |
| } |
| |
| public void setMatchingFallbacks(List<String> fallbacks) { |
| this.matchingFallbacks = ImmutableList.copyOf(fallbacks); |
| } |
| |
| public void setMatchingFallbacks(String fallback) { |
| this.matchingFallbacks = ImmutableList.of(fallback); |
| } |
| |
| /** |
| * Specifies a sorted list of build types that the plugin should try to use when a direct |
| * variant match with a local module dependency is not possible. |
| * |
| * <p>Android plugin 3.0.0 and higher try to match each variant of your module with the same one |
| * from its dependencies. For example, when you build a "freeDebug" version of your app, the |
| * plugin tries to match it with "freeDebug" versions of the local library modules the app |
| * depends on. |
| * |
| * <p>However, there may be situations in which <b>your app includes build types that a |
| * dependency does not</b>. For example, consider if your app includes a "stage" build type, but |
| * a dependency includes only a "debug" and "release" build type. When the plugin tries to build |
| * the "stage" version of your app, it won't know which version of the dependency to use, and |
| * you'll see an error message similar to the following: |
| * |
| * <pre> |
| * Error:Failed to resolve: Could not resolve project :mylibrary. |
| * Required by: |
| * project :app |
| * </pre> |
| * |
| * <p>In this situation, you can use <code>matchingFallbacks</code> to specify alternative |
| * matches for the app's "stage" build type, as shown below: |
| * |
| * <pre> |
| * // In the app's build.gradle file. |
| * android { |
| * buildTypes { |
| * release { |
| * // Because the dependency already includes a "release" build type, |
| * // you don't need to provide a list of fallbacks here. |
| * } |
| * stage { |
| * // Specifies a sorted list of fallback build types that the |
| * // plugin should try to use when a dependency does not include a |
| * // "stage" build type. You may specify as many fallbacks as you |
| * // like, and the plugin selects the first build type that's |
| * // available in the dependency. |
| * matchingFallbacks = ['debug', 'qa', 'release'] |
| * } |
| * } |
| * } |
| * </pre> |
| * |
| * <p>Note that there is no issue when a library dependency includes a build type that your app |
| * does not. That's because the plugin simply never requests that build type from the |
| * dependency. |
| * |
| * @return the names of product flavors to use, in descending priority order |
| */ |
| public List<String> getMatchingFallbacks() { |
| if (matchingFallbacks == null) { |
| return ImmutableList.of(); |
| } |
| return matchingFallbacks; |
| } |
| |
| @Override |
| @NonNull |
| public CoreNdkOptions getNdkConfig() { |
| return ndkConfig; |
| } |
| |
| @Override |
| @NonNull |
| public ExternalNativeBuildOptions getExternalNativeBuildOptions() { |
| return externalNativeBuildOptions; |
| } |
| |
| /** Options for configuration Java compilation. */ |
| @Override |
| @NonNull |
| public JavaCompileOptions getJavaCompileOptions() { |
| return javaCompileOptions; |
| } |
| |
| @NonNull |
| @Override |
| public CoreShaderOptions getShaders() { |
| return shaderOptions; |
| } |
| |
| /** |
| * Initialize the DSL object with the debug signingConfig. Not meant to be used from the build |
| * scripts. |
| */ |
| public void init(SigningConfig debugSigningConfig) { |
| init(); |
| if (BuilderConstants.DEBUG.equals(getName())) { |
| assert debugSigningConfig != null; |
| setSigningConfig(debugSigningConfig); |
| } |
| } |
| |
| /** |
| * Initialize the DSL object without the signingConfig. Not meant to be used from the build |
| * scripts. |
| */ |
| public void init() { |
| if (BuilderConstants.DEBUG.equals(getName())) { |
| setDebuggable(true); |
| setEmbedMicroApp(false); |
| isCrunchPngsDefault = false; |
| } |
| } |
| |
| /** The signing configuration. */ |
| @Override |
| @Nullable |
| public SigningConfig getSigningConfig() { |
| return (SigningConfig) super.getSigningConfig(); |
| } |
| |
| |
| /** {@inheritDoc} */ |
| @SuppressWarnings("UnnecessaryInheritDoc") |
| @Override |
| public Property<Boolean> getIsDefault() { |
| return isDefault; |
| } |
| |
| @Override |
| protected void _initWith(@NonNull BaseConfig that) { |
| super._initWith(that); |
| BuildType thatBuildType = (BuildType) that; |
| ndkConfig._initWith(thatBuildType.getNdkConfig()); |
| javaCompileOptions.getAnnotationProcessorOptions()._initWith( |
| thatBuildType.getJavaCompileOptions().getAnnotationProcessorOptions()); |
| shrinkResources = thatBuildType.isShrinkResources(); |
| shaderOptions._initWith(thatBuildType.getShaders()); |
| externalNativeBuildOptions._initWith(thatBuildType.getExternalNativeBuildOptions()); |
| useProguard = thatBuildType.isUseProguard(); |
| postProcessingBlock.initWith(((BuildType) that).getPostprocessing()); |
| crunchPngs = thatBuildType.isCrunchPngs(); |
| //noinspection deprecation Must still be copied. |
| isCrunchPngsDefault = thatBuildType.isCrunchPngsDefault(); |
| matchingFallbacks = ImmutableList.copyOf(thatBuildType.getMatchingFallbacks()); |
| // we don't want to dynamically link these values. We just want to copy the current value. |
| isDefault.set(thatBuildType.getIsDefault().get()); |
| } |
| |
| /** Override as DSL objects have no reason to be compared for equality. */ |
| @Override |
| public int hashCode() { |
| return System.identityHashCode(this); |
| } |
| |
| /** Override as DSL objects have no reason to be compared for equality. */ |
| @Override |
| public boolean equals(Object o) { |
| return this == o; |
| } |
| |
| // -- DSL Methods. TODO remove once the instantiator does what I expect it to do. |
| |
| /** |
| * Adds a new field to the generated BuildConfig class. |
| * |
| * <p>The field is generated as: {@code <type> <name> = <value>;} |
| * |
| * <p>This means each of these must have valid Java content. If the type is a String, then the |
| * value should include quotes. |
| * |
| * @param type the type of the field |
| * @param name the name of the field |
| * @param value the value of the field |
| */ |
| public void buildConfigField( |
| @NonNull String type, |
| @NonNull String name, |
| @NonNull String value) { |
| ClassField alreadyPresent = getBuildConfigFields().get(name); |
| if (alreadyPresent != null) { |
| String message = |
| String.format( |
| "BuildType(%s): buildConfigField '%s' value is being replaced: %s -> %s", |
| getName(), name, alreadyPresent.getValue(), value); |
| issueReporter.reportWarning(Type.GENERIC, message); |
| } |
| addBuildConfigField(new ClassFieldImpl(type, name, value)); |
| } |
| |
| /** |
| * Adds a new generated resource. |
| * |
| * <p>This is equivalent to specifying a resource in res/values. |
| * |
| * <p>See <a href="http://developer.android.com/guide/topics/resources/available-resources.html">Resource Types</a>. |
| * |
| * @param type the type of the resource |
| * @param name the name of the resource |
| * @param value the value of the resource |
| */ |
| public void resValue( |
| @NonNull String type, |
| @NonNull String name, |
| @NonNull String value) { |
| ClassField alreadyPresent = getResValues().get(name); |
| if (alreadyPresent != null) { |
| String message = |
| String.format( |
| "BuildType(%s): resValue '%s' value is being replaced: %s -> %s", |
| getName(), name, alreadyPresent.getValue(), value); |
| issueReporter.reportWarning(Type.GENERIC, message); |
| } |
| addResValue(new ClassFieldImpl(type, name, value)); |
| } |
| |
| /** |
| * Adds a new ProGuard configuration file. |
| * |
| * <p><code>proguardFile getDefaultProguardFile('proguard-android.txt')</code></p> |
| * |
| * <p>There are 2 default rules files |
| * <ul> |
| * <li>proguard-android.txt |
| * <li>proguard-android-optimize.txt |
| * </ul> |
| * <p>They are located in the SDK. Using <code>getDefaultProguardFile(String filename)</code> will return the |
| * full path to the files. They are identical except for enabling optimizations. |
| */ |
| @NonNull |
| public BuildType proguardFile(@NonNull Object proguardFile) { |
| checkPostProcessingConfiguration(PostProcessingConfiguration.OLD_DSL, "proguardFile"); |
| getProguardFiles().add(project.file(proguardFile)); |
| return this; |
| } |
| |
| /** |
| * Adds new ProGuard configuration files. |
| * |
| * <p>There are 2 default rules files |
| * <ul> |
| * <li>proguard-android.txt |
| * <li>proguard-android-optimize.txt |
| * </ul> |
| * <p>They are located in the SDK. Using <code>getDefaultProguardFile(String filename)</code> will return the |
| * full path to the files. They are identical except for enabling optimizations. |
| */ |
| @NonNull |
| public BuildType proguardFiles(@NonNull Object... files) { |
| checkPostProcessingConfiguration(PostProcessingConfiguration.OLD_DSL, "proguardFiles"); |
| for (Object file : files) { |
| proguardFile(file); |
| } |
| return this; |
| } |
| |
| /** |
| * Sets the ProGuard configuration files. |
| * |
| * <p>There are 2 default rules files |
| * <ul> |
| * <li>proguard-android.txt |
| * <li>proguard-android-optimize.txt |
| * </ul> |
| * <p>They are located in the SDK. Using <code>getDefaultProguardFile(String filename)</code> will return the |
| * full path to the files. They are identical except for enabling optimizations. |
| */ |
| @NonNull |
| public BuildType setProguardFiles(@NonNull Iterable<?> proguardFileIterable) { |
| checkPostProcessingConfiguration(PostProcessingConfiguration.OLD_DSL, "setProguardFiles"); |
| getProguardFiles().clear(); |
| proguardFiles(Iterables.toArray(proguardFileIterable, Object.class)); |
| return this; |
| } |
| |
| /** |
| * Adds a proguard rule file to be used when processing test code. |
| * |
| * <p>Test code needs to be processed to apply the same obfuscation as was done to main code. |
| */ |
| @NonNull |
| public BuildType testProguardFile(@NonNull Object proguardFile) { |
| checkPostProcessingConfiguration(PostProcessingConfiguration.OLD_DSL, "testProguardFile"); |
| getTestProguardFiles().add(project.file(proguardFile)); |
| return this; |
| } |
| |
| /** |
| * Adds proguard rule files to be used when processing test code. |
| * |
| * <p>Test code needs to be processed to apply the same obfuscation as was done to main code. |
| */ |
| @NonNull |
| public BuildType testProguardFiles(@NonNull Object... proguardFiles) { |
| checkPostProcessingConfiguration(PostProcessingConfiguration.OLD_DSL, "testProguardFiles"); |
| for (Object proguardFile : proguardFiles) { |
| testProguardFile(proguardFile); |
| } |
| return this; |
| } |
| |
| /** |
| * Specifies proguard rule files to be used when processing test code. |
| * |
| * <p>Test code needs to be processed to apply the same obfuscation as was done to main code. |
| */ |
| @NonNull |
| public BuildType setTestProguardFiles(@NonNull Iterable<?> files) { |
| checkPostProcessingConfiguration( |
| PostProcessingConfiguration.OLD_DSL, "setTestProguardFiles"); |
| getTestProguardFiles().clear(); |
| testProguardFiles(Iterables.toArray(files, Object.class)); |
| return this; |
| } |
| |
| /** |
| * Adds a proguard rule file to be included in the published AAR. |
| * |
| * <p>This proguard rule file will then be used by any application project that consume the AAR |
| * (if proguard is enabled). |
| * |
| * <p>This allows AAR to specify shrinking or obfuscation exclude rules. |
| * |
| * <p>This is only valid for Library project. This is ignored in Application project. |
| */ |
| @NonNull |
| public BuildType consumerProguardFile(@NonNull Object proguardFile) { |
| checkPostProcessingConfiguration( |
| PostProcessingConfiguration.OLD_DSL, "consumerProguardFile"); |
| getConsumerProguardFiles().add(project.file(proguardFile)); |
| return this; |
| } |
| |
| /** |
| * Adds proguard rule files to be included in the published AAR. |
| * |
| * <p>This proguard rule file will then be used by any application project that consume the AAR |
| * (if proguard is enabled). |
| * |
| * <p>This allows AAR to specify shrinking or obfuscation exclude rules. |
| * |
| * <p>This is only valid for Library project. This is ignored in Application project. |
| */ |
| @NonNull |
| public BuildType consumerProguardFiles(@NonNull Object... proguardFiles) { |
| checkPostProcessingConfiguration( |
| PostProcessingConfiguration.OLD_DSL, "consumerProguardFiles"); |
| for (Object proguardFile : proguardFiles) { |
| consumerProguardFile(proguardFile); |
| } |
| |
| return this; |
| } |
| |
| /** |
| * Specifies a proguard rule file to be included in the published AAR. |
| * |
| * <p>This proguard rule file will then be used by any application project that consume the AAR |
| * (if proguard is enabled). |
| * |
| * <p>This allows AAR to specify shrinking or obfuscation exclude rules. |
| * |
| * <p>This is only valid for Library project. This is ignored in Application project. |
| */ |
| @NonNull |
| public BuildType setConsumerProguardFiles(@NonNull Iterable<?> proguardFileIterable) { |
| checkPostProcessingConfiguration( |
| PostProcessingConfiguration.OLD_DSL, "setConsumerProguardFiles"); |
| getConsumerProguardFiles().clear(); |
| consumerProguardFiles(Iterables.toArray(proguardFileIterable, Object.class)); |
| return this; |
| } |
| |
| |
| public void ndk(@NonNull Action<NdkOptions> action) { |
| action.execute(ndkConfig); |
| } |
| |
| /** |
| * Configure native build options. |
| */ |
| public ExternalNativeBuildOptions externalNativeBuild(@NonNull Action<ExternalNativeBuildOptions> action) { |
| action.execute(externalNativeBuildOptions); |
| return externalNativeBuildOptions; |
| } |
| |
| /** |
| * Configure shader compiler options for this build type. |
| */ |
| public void shaders(@NonNull Action<ShaderOptions> action) { |
| action.execute(shaderOptions); |
| } |
| |
| @NonNull |
| @Override |
| public com.android.builder.model.BuildType setMinifyEnabled(boolean enabled) { |
| checkPostProcessingConfiguration(PostProcessingConfiguration.OLD_DSL, "setMinifyEnabled"); |
| return super.setMinifyEnabled(enabled); |
| } |
| |
| /** |
| * Whether removal of unused java code is enabled. |
| * |
| * <p>Default is false. |
| */ |
| @Override |
| public boolean isMinifyEnabled() { |
| // Try to return a sensible value for the model and third party plugins inspecting the DSL. |
| if (postProcessingConfiguration != PostProcessingConfiguration.POSTPROCESSING_BLOCK) { |
| return super.isMinifyEnabled(); |
| } else { |
| return postProcessingBlock.isRemoveUnusedCode() |
| || postProcessingBlock.isObfuscate() |
| || postProcessingBlock.isOptimizeCode(); |
| } |
| } |
| |
| /** |
| * Whether shrinking of unused resources is enabled. |
| * |
| * Default is false; |
| */ |
| @Override |
| public boolean isShrinkResources() { |
| // Try to return a sensible value for the model and third party plugins inspecting the DSL. |
| if (postProcessingConfiguration != PostProcessingConfiguration.POSTPROCESSING_BLOCK) { |
| return shrinkResources; |
| } else { |
| return postProcessingBlock.isRemoveUnusedResources(); |
| } |
| } |
| |
| public void setShrinkResources(boolean shrinkResources) { |
| checkPostProcessingConfiguration(PostProcessingConfiguration.OLD_DSL, "setShrinkResources"); |
| this.shrinkResources = shrinkResources; |
| } |
| |
| /** |
| * Specifies whether to always use ProGuard for code and resource shrinking. |
| * |
| * <p>By default, when you enable code shrinking by setting <a |
| * href="com.android.build.gradle.internal.dsl.BuildType.html#com.android.build.gradle.internal.dsl.BuildType:minifyEnabled"> |
| * <code>minifyEnabled</code></a> to <code>true</code>, the Android plugin uses R8. If you set |
| * this property to <code>true</code>, the Android plugin uses ProGuard. |
| * |
| * <p>To learn more, read <a |
| * href="https://developer.android.com/studio/build/shrink-code.html">Shrink, obfuscate, and |
| * optimize your app</a>. |
| */ |
| @Override |
| public Boolean isUseProguard() { |
| // Try to return a sensible value for the model and third party plugins inspecting the DSL. |
| if (postProcessingConfiguration != PostProcessingConfiguration.POSTPROCESSING_BLOCK) { |
| return useProguard; |
| } else { |
| return postProcessingBlock.getCodeShrinkerEnum() == CodeShrinker.PROGUARD; |
| } |
| } |
| |
| public void setUseProguard(boolean useProguard) { |
| checkPostProcessingConfiguration(PostProcessingConfiguration.OLD_DSL, "setUseProguard"); |
| if (dslChecksEnabled.get()) { |
| deprecationReporter.reportObsoleteUsage( |
| "useProguard", DeprecationReporter.DeprecationTarget.DSL_USE_PROGUARD); |
| } |
| } |
| |
| /** {@inheritDoc} */ |
| @Override |
| public Boolean isCrunchPngs() { |
| return crunchPngs; |
| } |
| |
| public void setCrunchPngs(Boolean crunchPngs) { |
| this.crunchPngs = crunchPngs; |
| } |
| |
| /* |
| * (Non javadoc): Whether png crunching should be enabled if not explicitly overridden. |
| * |
| * Can be removed once the AaptOptions crunch method is removed. |
| */ |
| @Override |
| @Deprecated |
| public boolean isCrunchPngsDefault() { |
| return isCrunchPngsDefault; |
| } |
| |
| /** This DSL is incubating and subject to change. */ |
| @Incubating |
| @Internal |
| @NonNull |
| public PostProcessingBlock getPostprocessing() { |
| checkPostProcessingConfiguration( |
| PostProcessingConfiguration.POSTPROCESSING_BLOCK, "getPostProcessing"); |
| return postProcessingBlock; |
| } |
| |
| /** This DSL is incubating and subject to change. */ |
| @Incubating |
| @Internal |
| public void postprocessing(@NonNull Action<PostProcessingBlock> action) { |
| checkPostProcessingConfiguration( |
| PostProcessingConfiguration.POSTPROCESSING_BLOCK, "postProcessing"); |
| action.execute(postProcessingBlock); |
| } |
| |
| /** Describes how postProcessing was configured. Not to be used from the DSL. */ |
| @NonNull |
| public PostProcessingConfiguration getPostProcessingConfiguration() { |
| // If the user didn't configure anything, stick to the old DSL. |
| return postProcessingConfiguration != null |
| ? postProcessingConfiguration |
| : PostProcessingConfiguration.OLD_DSL; |
| } |
| |
| /** |
| * Checks that the user is consistently using either the new or old DSL for configuring bytecode |
| * postProcessing. |
| */ |
| private void checkPostProcessingConfiguration( |
| @NonNull PostProcessingConfiguration used, @NonNull String methodName) { |
| if (!dslChecksEnabled.get()) { |
| return; |
| } |
| |
| if (this.postProcessingConfiguration == null) { |
| this.postProcessingConfiguration = used; |
| this.postProcessingDslMethodUsed = methodName; |
| } else if (this.postProcessingConfiguration != used) { |
| assert postProcessingDslMethodUsed != null; |
| String message; |
| switch (used) { |
| case POSTPROCESSING_BLOCK: |
| // TODO: URL with more details. |
| message = |
| String.format( |
| "The `postProcessing` block cannot be used with together with the `%s` method.", |
| postProcessingDslMethodUsed); |
| break; |
| case OLD_DSL: |
| // TODO: URL with more details. |
| message = |
| String.format( |
| "The `%s` method cannot be used with together with the `postProcessing` block.", |
| methodName); |
| break; |
| default: |
| throw new AssertionError("Unknown value " + used); |
| } |
| issueReporter.reportError(Type.GENERIC, message, methodName); |
| } |
| } |
| |
| @Override |
| public BuildType initWith(com.android.builder.model.BuildType that) { |
| // we need to avoid doing this because of Property objects that cannot |
| // be set from themselves |
| if (that == this) { |
| return this; |
| } |
| dslChecksEnabled.set(false); |
| try { |
| return (BuildType) super.initWith(that); |
| } finally { |
| dslChecksEnabled.set(true); |
| } |
| } |
| } |