112 lines
4.1 KiB
Java
112 lines
4.1 KiB
Java
/*
|
|
* Copyright (C) 2022 The Dagger Authors.
|
|
*
|
|
* 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 dagger.internal.codegen.writing;
|
|
|
|
import static dagger.spi.model.BindingKind.DELEGATE;
|
|
|
|
import dagger.internal.codegen.binding.ContributionBinding;
|
|
import dagger.internal.codegen.writing.ComponentImplementation.CompilerMode;
|
|
import dagger.spi.model.BindingKind;
|
|
|
|
/** Generation mode for satisfying framework request to Provision Binding. */
|
|
enum FrameworkInstanceKind {
|
|
SWITCHING_PROVIDER,
|
|
EXPERIMENTAL_SWITCHING_PROVIDER,
|
|
STATIC_FACTORY,
|
|
PROVIDER_FIELD;
|
|
|
|
public static FrameworkInstanceKind from(ContributionBinding binding, CompilerMode compilerMode) {
|
|
if (usesSwitchingProvider(binding, compilerMode)) {
|
|
if (compilerMode.isExperimentalMergedMode()) {
|
|
return EXPERIMENTAL_SWITCHING_PROVIDER;
|
|
} else if (compilerMode.isFastInit()) {
|
|
return SWITCHING_PROVIDER;
|
|
} else {
|
|
throw new IllegalStateException(
|
|
"Compiler mode " + compilerMode + " cannot use Switching Provider.");
|
|
}
|
|
} else if (usesStaticFactoryCreation(binding, compilerMode)) {
|
|
return STATIC_FACTORY;
|
|
} else {
|
|
return PROVIDER_FIELD;
|
|
}
|
|
}
|
|
|
|
private static boolean usesSwitchingProvider(
|
|
ContributionBinding binding, CompilerMode compilerMode) {
|
|
if (!compilerMode.isFastInit() && !compilerMode.isExperimentalMergedMode()) {
|
|
return false;
|
|
}
|
|
// TODO(wanyingd): remove this check once we allow inaccessible types in merged mode.
|
|
if (compilerMode.isExperimentalMergedMode()
|
|
&& binding.kind().equals(BindingKind.ASSISTED_FACTORY)) {
|
|
return false;
|
|
}
|
|
switch (binding.kind()) {
|
|
case ASSISTED_INJECTION:
|
|
case BOUND_INSTANCE:
|
|
case COMPONENT:
|
|
case COMPONENT_DEPENDENCY:
|
|
case DELEGATE:
|
|
case MEMBERS_INJECTOR: // TODO(b/199889259): Consider optimizing this for fastInit mode.
|
|
// These binding kinds avoid SwitchingProvider when the backing instance already exists,
|
|
// e.g. a component provider can use FactoryInstance.create(this).
|
|
return false;
|
|
case MULTIBOUND_SET:
|
|
case MULTIBOUND_MAP:
|
|
case OPTIONAL:
|
|
// These binding kinds avoid SwitchingProvider when their are no dependencies,
|
|
// e.g. a multibound set with no dependency can use a singleton, SetFactory.empty().
|
|
return !binding.dependencies().isEmpty();
|
|
case INJECTION:
|
|
case PROVISION:
|
|
case ASSISTED_FACTORY:
|
|
case COMPONENT_PROVISION:
|
|
case SUBCOMPONENT_CREATOR:
|
|
case PRODUCTION:
|
|
case COMPONENT_PRODUCTION:
|
|
case MEMBERS_INJECTION:
|
|
return true;
|
|
}
|
|
throw new AssertionError(String.format("No such binding kind: %s", binding.kind()));
|
|
}
|
|
|
|
private static boolean usesStaticFactoryCreation(
|
|
ContributionBinding binding, CompilerMode compilerMode) {
|
|
// If {@code binding} is an unscoped provision binding with no factory arguments, then
|
|
// we don't need a field to hold its factory. In that case, this method returns the static
|
|
// select that returns the factory.
|
|
// member
|
|
if (!binding.dependencies().isEmpty() || binding.scope().isPresent()) {
|
|
return false;
|
|
}
|
|
switch (binding.kind()) {
|
|
case MULTIBOUND_MAP:
|
|
case MULTIBOUND_SET:
|
|
return true;
|
|
case PROVISION:
|
|
return !compilerMode.isFastInit()
|
|
&& !compilerMode.isExperimentalMergedMode()
|
|
&& !binding.requiresModuleInstance();
|
|
case INJECTION:
|
|
return !compilerMode.isFastInit() && !compilerMode.isExperimentalMergedMode();
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
}
|