下面列出了com.google.common.collect.ImmutableList#get ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Test
public void singleSlice() throws Exception {
BundleModule testModule =
new BundleModuleBuilder(MODULE_NAME)
.addFile("assets/image.jpg")
.addFile("assets/image2.jpg")
.setManifest(androidManifestForAssetModule("com.test.app"))
.build();
assertThat(testModule.getModuleType()).isEqualTo(ModuleType.ASSET_MODULE);
ImmutableList<ModuleSplit> slices =
new AssetModuleSplitter(testModule, ApkGenerationConfiguration.getDefaultInstance())
.splitModule();
assertThat(slices).hasSize(1);
ModuleSplit masterSlice = slices.get(0);
assertThat(masterSlice.getSplitType()).isEqualTo(SplitType.ASSET_SLICE);
assertThat(masterSlice.isMasterSplit()).isTrue();
assertThat(masterSlice.getAndroidManifest().getSplitId()).hasValue(MODULE_NAME);
assertThat(masterSlice.getAndroidManifest().getHasCode()).hasValue(false);
assertThat(masterSlice.getApkTargeting()).isEqualToDefaultInstance();
assertThat(extractPaths(masterSlice.getEntries()))
.containsExactly("assets/image.jpg", "assets/image2.jpg");
}
@Test
public void testParse_sourceAndTarget_match()
throws URISyntaxException, IOException, SAXException, VerifierConfigurationException {
Path exclusionFile = absolutePathOfResource("exclusion-sample-rules/source-and-target.xml");
ImmutableList<LinkageErrorMatcher> matchers = ExclusionFiles.parse(exclusionFile);
Truth.assertThat(matchers).hasSize(1);
LinkageErrorMatcher matcher = matchers.get(0);
SymbolProblem symbolProblemToMatch =
new SymbolProblem(
new MethodSymbol("com.google.Foo", "methodA", "()Ljava.lang.String;", false),
ErrorType.INACCESSIBLE_MEMBER,
new ClassFile(new ClassPathEntry(Paths.get("dummy.jar")), "com.google.Foo"));
boolean result =
matcher.match(
symbolProblemToMatch,
new ClassFile(
new ClassPathEntry(Paths.get("dummy.jar")), "reactor.core.publisher.Traces"));
assertTrue(result);
}
private int installSinglePackage(String packageName, ImmutableList<InstallableApk> apks) {
logger.info(String.format("Installing %s", packageName));
int childSessionId = createChildSession(apks);
for (int index = 0; index < apks.size(); index++) {
InstallableApk apkToInstall = apks.get(index);
logger.info(String.format("\tWriting %s", apkToInstall.getPath().getFileName()));
Path remotePath = syncPackageToDevice(apkToInstall.getPath());
try {
installRemoteApk(childSessionId, packageName + "_" + index, remotePath);
} finally {
removePackageFromDevice(remotePath);
}
}
return childSessionId;
}
/**
* Creates a list of actual arguments that contains the given arguments and all attribute values
* required from the specified context.
*/
private ImmutableList<Object> buildArgumentList(ClassObject ctx, Object... arguments)
throws EvalException {
ImmutableList.Builder<Object> builder = ImmutableList.builder();
ImmutableList<String> names = getParameterNames();
int requiredParameters = names.size() - arguments.length;
for (int pos = 0; pos < requiredParameters; ++pos) {
String name = names.get(pos);
Object value = ctx.getValue(name);
if (value == null) {
throw new IllegalArgumentException(ctx.getErrorMessageForUnknownField(name));
}
builder.add(value);
}
return builder.add(arguments).build();
}
@Test
public void upfrontAssetModule_addsVersionCode() throws Exception {
AppBundle appBundle =
createAppBundle(
new BundleModuleBuilder("asset_module")
.setManifest(androidManifestForAssetModule(PACKAGE_NAME, withInstallTimeDelivery()))
.build());
ImmutableList<ModuleSplit> assetSlices =
new AssetSlicesGenerator(appBundle, ApkGenerationConfiguration.getDefaultInstance())
.generateAssetSlices();
assertThat(assetSlices).hasSize(1);
ModuleSplit assetSlice = assetSlices.get(0);
assertThat(assetSlice.getAndroidManifest().getVersionCode()).hasValue(VERSION_CODE);
}
@Test
public void testParse_targetPackage_unmatch()
throws URISyntaxException, IOException, SAXException, VerifierConfigurationException {
Path exclusionFile = absolutePathOfResource("exclusion-sample-rules/target-package.xml");
ImmutableList<LinkageErrorMatcher> matchers = ExclusionFiles.parse(exclusionFile);
Truth.assertThat(matchers).hasSize(1);
LinkageErrorMatcher matcher = matchers.get(0);
// Package com.googler is not a subpackage of com.google.
SymbolProblem symbolProblemToMatch =
new SymbolProblem(
new MethodSymbol("com.googler.Foo", "methodA", "()Ljava.lang.String;", false),
ErrorType.INACCESSIBLE_MEMBER,
new ClassFile(new ClassPathEntry(Paths.get("dummy.jar")), "com.googler.Foo"));
boolean result =
matcher.match(
symbolProblemToMatch,
new ClassFile(
new ClassPathEntry(Paths.get("dummy.jar")), "reactor.core.publisher.Traces"));
assertFalse(result);
}
@Test
public void manyModulesShardByAbiAndDensity_havingNoAbiAndNoResources_producesOneApk()
throws Exception {
BundleModule baseModule =
new BundleModuleBuilder("base")
.addFile("dex/classes.dex")
.addFile("root/license.dat")
.setManifest(androidManifest("com.test.app"))
.build();
BundleModule featureModule =
new BundleModuleBuilder("feature")
.addFile("assets/file.txt")
.setManifest(androidManifest("com.test.app"))
.build();
ImmutableList<ModuleSplit> shards =
bundleSharder.shardBundle(
ImmutableList.of(baseModule, featureModule),
ImmutableSet.of(OptimizationDimension.ABI, OptimizationDimension.SCREEN_DENSITY),
DEFAULT_METADATA);
assertThat(shards).hasSize(1);
ModuleSplit fatShard = shards.get(0);
assertThat(fatShard.getApkTargeting()).isEqualToDefaultInstance();
assertThat(fatShard.getVariantTargeting()).isEqualToDefaultInstance();
assertThat(fatShard.getSplitType()).isEqualTo(SplitType.STANDALONE);
assertThat(extractPaths(fatShard.getEntries()))
.containsExactly("assets/file.txt", "dex/classes.dex", "root/license.dat");
}
@Test
public void nonInstantActivityRemovedForInstantManifest() throws Exception {
XmlNode manifest =
androidManifest(
"com.test.app",
withMainActivity("MainActivity"),
withSplitNameActivity("FooActivity", "onDemandModule"));
BundleModule bundleModule =
new BundleModuleBuilder("onDemandModule").setManifest(manifest).build();
ImmutableList<ModuleSplit> moduleSplits =
ModuleSplitter.createNoStamp(
bundleModule,
BUNDLETOOL_VERSION,
ApkGenerationConfiguration.builder().setForInstantAppVariants(true).build(),
lPlusVariantTargeting(),
ImmutableSet.of())
.splitModule();
assertThat(moduleSplits).hasSize(1);
ModuleSplit masterSplit = moduleSplits.get(0);
ImmutableList<XmlElement> activities =
masterSplit
.getAndroidManifest()
.getManifestRoot()
.getElement()
.getChildElement("application")
.getChildrenElements(ACTIVITY_ELEMENT_NAME)
.map(XmlProtoElement::getProto)
.collect(toImmutableList());
assertThat(activities).hasSize(1);
XmlElement activityElement = activities.get(0);
assertThat(activityElement.getAttributeList())
.containsExactly(
xmlAttribute(ANDROID_NAMESPACE_URI, "name", NAME_RESOURCE_ID, "MainActivity"));
}
@Test
public void testMultipleDirCacheSettings() throws IOException {
ArtifactCacheBuckConfig config =
createFromText(
"[cache]",
"dir_cache_names = name1, othername",
"[cache#name1]",
"dir = cache_dir_name1",
"dir_mode = readwrite",
"dir_max_size = 1022B",
"[cache#othername]",
"dir = othername_dir_cache",
"dir_mode = readonly",
"dir_max_size = 800B");
ImmutableList<DirCacheEntry> entries =
ImmutableList.copyOf(config.getCacheEntries().getDirCacheEntries());
DirCacheEntry name1Entry = entries.get(0);
assertThat(
name1Entry.getCacheDir(), Matchers.equalTo(Paths.get("cache_dir_name1").toAbsolutePath()));
assertThat(name1Entry.getCacheReadMode(), Matchers.equalTo(CacheReadMode.READWRITE));
assertThat(name1Entry.getMaxSizeBytes(), Matchers.equalTo(Optional.of(1022L)));
DirCacheEntry othernameDirCche = entries.get(1);
assertThat(
othernameDirCche.getCacheDir(),
Matchers.equalTo(Paths.get("othername_dir_cache").toAbsolutePath()));
assertThat(othernameDirCche.getCacheReadMode(), Matchers.equalTo(CacheReadMode.READONLY));
assertThat(othernameDirCche.getMaxSizeBytes(), Matchers.equalTo(Optional.of(800L)));
}
private static int find(ImmutableList<Lattice.Measure> measures,
Pair<SqlAggFunction, List<Integer>> seek) {
for (int i = 0; i < measures.size(); i++) {
Lattice.Measure measure = measures.get(i);
if (measure.agg.equals(seek.left)
&& measure.argOrdinals().equals(seek.right)) {
return i;
}
}
return -1;
}
@Override
protected void useConfiguration(String... args) throws Exception {
ImmutableList<String> extraArgs = MockObjcSupport.requiredObjcCrosstoolFlags();
args = Arrays.copyOf(args, args.length + extraArgs.size());
for (int i = 0; i < extraArgs.size(); i++) {
args[(args.length - extraArgs.size()) + i] = extraArgs.get(i);
}
super.useConfiguration(args);
}
private static ImmutableList<ScriptChunk> optimize(ImmutableList<ScriptChunk> scriptChunks) {
if (scriptChunks.size() == 0 || scriptChunks.size() == 1) {
return scriptChunks;
}
ScriptChunk ch1 = scriptChunks.get(0);
ScriptChunk ch2 = scriptChunks.get(1);
if (ch1.equalsOpCode(ScriptOpCodes.OP_TOALTSTACK) && ch2.equalsOpCode(ScriptOpCodes.OP_FROMALTSTACK)) {
return optimize(scriptChunks.subList(2, scriptChunks.size()));
}
return ImmutableList.<ScriptChunk>builder().add(scriptChunks.get(0))
.addAll(optimize(scriptChunks.subList(1, scriptChunks.size()))).build();
}
@Override
public Change<GitRevision> change(GitRevision ref)
throws RepoException, ValidationException {
// The limit=1 flag guarantees that only one change is returned
ChangeReader changeReader = changeReaderBuilder(repoUrl)
.setLimit(1)
.setFirstParent(firstParent)
.build();
ImmutableList<Change<GitRevision>> changes = changeReader.run(ref.getSha1());
if (changes.isEmpty()) {
throw new EmptyChangeException(
String.format(
"'%s' revision cannot be found in the origin or it didn't affect the origin paths.",
ref.asString()));
}
// 'git log -1 -m' for a merge commit returns two entries :(
Change<GitRevision> rev = changes.get(0);
// Keep the original revision since it might have context information like code review
// info. The difference with changes method is that here we know exactly what we've
// requested (One SHA-1 revision) while in the other we get a result for a range. That
// means that extensions of GitOrigin need to implement changes if they want to provide
// additional information.
return new Change<>(ref, rev.getAuthor(), rev.getMessage(), rev.getDateTime(),
rev.getLabels(), rev.getChangeFiles(), rev.isMerge(), rev.getParents());
}
private <T extends Interceptor> @NotNull ImmutableList<T> filterInterceptorsOfExtension(
final @NotNull ImmutableList<T> interceptors,
final @NotNull IsolatedPluginClassloader extensionClassloader) {
final ImmutableList.Builder<T> builder = ImmutableList.builder();
for (int i = 0; i < interceptors.size(); i++) {
final T interceptor = interceptors.get(i);
if (interceptor.getClass().getClassLoader().equals(extensionClassloader)) {
builder.add(interceptor);
}
}
return builder.build();
}
@Test
@Theory
public void shardByAbi_havingSingleAbi_producesOneApk(
@FromDataPoints("deviceSpecs") Optional<DeviceSpec> deviceSpec) throws Exception {
bundleSharder =
new BundleSharder(
tmpDir,
BundleToolVersion.getCurrentVersion(),
BundleSharderConfiguration.builder().setDeviceSpec(deviceSpec).build());
BundleModule bundleModule =
new BundleModuleBuilder("base")
.addFile("assets/file.txt")
.addFile("dex/classes.dex")
.addFile("lib/x86_64/libtest.so")
.addFile("res/drawable/image.jpg")
.addFile("res/drawable-mdpi/image.jpg")
.addFile("root/license.dat")
.setManifest(androidManifest("com.test.app"))
.setNativeConfig(
nativeLibraries(
targetedNativeDirectory("lib/x86_64", nativeDirectoryTargeting(X86_64))))
.setResourceTable(
new ResourceTableBuilder()
.addPackage("com.test.app")
.addDrawableResourceForMultipleDensities(
"image",
ImmutableMap.of(
DEFAULT_DENSITY_VALUE,
"res/drawable/image.jpg",
MDPI_VALUE,
"res/drawable-mdpi/image.jpg"))
.build())
.build();
ImmutableList<ModuleSplit> shards;
if (deviceSpec.isPresent()) {
ShardedSystemSplits shardedSystemSplits =
bundleSharder.shardForSystemApps(
/* modules= */ ImmutableList.of(bundleModule),
/* modulesToFuse= */ ImmutableSet.of(BASE_MODULE_NAME),
ImmutableSet.of(OptimizationDimension.ABI),
DEFAULT_METADATA);
assertThat(shardedSystemSplits.getAdditionalSplits()).isEmpty();
shards = ImmutableList.of(shardedSystemSplits.getSystemImageSplit());
} else {
shards =
bundleSharder.shardBundle(
ImmutableList.of(bundleModule),
ImmutableSet.of(OptimizationDimension.ABI),
DEFAULT_METADATA);
}
assertThat(shards).hasSize(1);
ModuleSplit fatShard = shards.get(0);
assertThat(fatShard.getApkTargeting()).isEqualTo(apkAbiTargeting(AbiAlias.X86_64));
assertThat(fatShard.getVariantTargeting()).isEqualToDefaultInstance();
assertThat(fatShard.getSplitType()).isEqualTo(SplitType.STANDALONE);
assertThat(extractPaths(fatShard.getEntries()))
.containsExactly(
"assets/file.txt",
"dex/classes.dex",
"lib/x86_64/libtest.so",
"res/drawable/image.jpg",
"res/drawable-mdpi/image.jpg",
"root/license.dat");
}
@Test
public void test_loadAllDates() {
LocalDate sampleDate = ALL_DATES.get(3); // 2017-04-21
ImmutableList<LocalDate> expDates = ImmutableList.of(
LocalDate.of(2017, 7, 21), LocalDate.of(2017, 10, 7), LocalDate.of(2018, 4, 13), LocalDate.of(2019, 4, 12),
LocalDate.of(2020, 3, 20), LocalDate.of(2021, 3, 19), LocalDate.of(2022, 3, 19), LocalDate.of(2023, 3, 17),
LocalDate.of(2024, 6, 17), LocalDate.of(2025, 3, 18), LocalDate.of(2026, 3, 20), LocalDate.of(2027, 3, 20),
LocalDate.of(2031, 12, 19), LocalDate.of(2037, 3, 17), LocalDate.of(2047, 3, 17), LocalDate.of(2056, 3, 17));
ImmutableList<String> expTenors = ImmutableList.of(
"3M", "6M", "1Y", "2Y", "3Y", "4Y", "5Y", "6Y", "7Y", "8Y", "9Y", "10Y", "15Y", "20Y", "30Y", "40Y");
RepoGroup repoGroup = RepoGroup.of("JP-REPO");
DoubleArray expRepoXValues = DoubleArray.of(3, n -> ACT_365F.relativeYearFraction(sampleDate, expDates.get(n)));
DoubleArray expRepoYValues = DoubleArray.of(-0.0019521, -0.0016021, -0.0022521);
ImmutableList<LabelDateParameterMetadata> expRepoMetadata = IntStream.range(0, 3)
.mapToObj(n -> LabelDateParameterMetadata.of(expDates.get(n), expTenors.get(n)))
.collect(Guavate.toImmutableList());
LegalEntityGroup legalEntityGroup = LegalEntityGroup.of("JP-GOVT");
DoubleArray expIssuerXValues =
DoubleArray.of(expDates.size(), n -> ACT_365F.relativeYearFraction(sampleDate, expDates.get(n)));
DoubleArray expIssuerYValues = DoubleArray.of(
-0.0019511690511744527, -0.001497422302092893, -0.0021798583657932176, -0.002215700360912938, -0.0021722324679574866,
-0.001922059591219172, -0.0015461646763548528, -0.0014835851245462084, -0.001118669580570464, -5.476767138782941E-4,
-2.2155596172855965E-4, 2.0333291172821893E-5, 0.00284500423293463, 0.005876533417933958, 0.007957581583531789,
0.009134630405512047);
ImmutableList<LabelDateParameterMetadata> expIssuerMetadata = IntStream.range(0, expDates.size())
.mapToObj(n -> LabelDateParameterMetadata.of(expDates.get(n), expTenors.get(n)))
.collect(Guavate.toImmutableList());
ImmutableListMultimap<LocalDate, LegalEntityCurveGroup> allCurves = LegalEntityRatesCurvesCsvLoader.loadAllDates(
ResourceLocator.of(GROUPS),
ResourceLocator.of(SETTINGS),
ImmutableList.of(ResourceLocator.of(CURVES_1), ResourceLocator.of(CURVES_2)));
assertThat(allCurves.keySet().containsAll(ALL_DATES)).isTrue();
ImmutableList<LegalEntityCurveGroup> groups = allCurves.get(sampleDate);
assertThat(groups).hasSize(2);
// group 0
LegalEntityCurveGroup group0 = groups.get(0);
assertThat(group0.getName()).isEqualTo(CurveGroupName.of("Default1"));
// repo
assertThat(group0.getRepoCurves()).hasSize(1);
Curve repoCurve = group0.getRepoCurves().get(Pair.of(repoGroup, JPY));
InterpolatedNodalCurve expectedRepoCurve = InterpolatedNodalCurve.of(
Curves.zeroRates(CurveName.of("JP-REPO-1"), ACT_365F, expRepoMetadata),
expRepoXValues, expRepoYValues, CurveInterpolators.LINEAR, CurveExtrapolators.FLAT, CurveExtrapolators.FLAT);
assertThat(repoCurve).isEqualTo(expectedRepoCurve);
// issuer
assertThat(group0.getIssuerCurves()).hasSize(2);
Curve issuerCurve = group0.getIssuerCurves().get(Pair.of(legalEntityGroup, JPY));
InterpolatedNodalCurve expectedIssuerCurve = InterpolatedNodalCurve.of(
Curves.zeroRates(CurveName.of("JP-GOVT-1"), ACT_365F, expIssuerMetadata),
expIssuerXValues, expIssuerYValues, CurveInterpolators.LINEAR, CurveExtrapolators.FLAT, CurveExtrapolators.FLAT);
assertThat(issuerCurve).isEqualTo(expectedIssuerCurve);
Curve usIssuerCurve = group0.getIssuerCurves().get(Pair.of(LegalEntityGroup.of("US-GOVT"), USD));
expectedIssuerCurve = InterpolatedNodalCurve.of(
Curves.zeroRates(CurveName.of("US-GOVT"), ACT_360, expIssuerMetadata),
DoubleArray.of(expDates.size(), n -> ACT_360.relativeYearFraction(sampleDate, expDates.get(n))),
expIssuerYValues, CurveInterpolators.NATURAL_SPLINE, CurveExtrapolators.FLAT, CurveExtrapolators.FLAT);
assertThat(usIssuerCurve).isEqualTo(expectedIssuerCurve);
// group 1
LegalEntityCurveGroup group1 = groups.get(1);
assertThat(group1.getName()).isEqualTo(CurveGroupName.of("Default2"));
// repo
repoCurve = group1.getRepoCurves().get(Pair.of(repoGroup, JPY));
expectedRepoCurve = InterpolatedNodalCurve.of(
Curves.zeroRates(CurveName.of("JP-REPO-2"), ACT_365F, expRepoMetadata),
expRepoXValues, expRepoYValues, CurveInterpolators.DOUBLE_QUADRATIC, CurveExtrapolators.LINEAR,
CurveExtrapolators.LINEAR);
assertThat(repoCurve).isEqualTo(expectedRepoCurve);
// issuer
assertThat(group1.getIssuerCurves()).hasSize(1);
issuerCurve = group1.getIssuerCurves().get(Pair.of(legalEntityGroup, JPY));
expectedIssuerCurve = InterpolatedNodalCurve.of(
Curves.zeroRates(CurveName.of("JP-GOVT-2"), ACT_365F, expIssuerMetadata),
expIssuerXValues, expIssuerYValues, CurveInterpolators.DOUBLE_QUADRATIC, CurveExtrapolators.LINEAR,
CurveExtrapolators.LINEAR);
assertThat(issuerCurve).isEqualTo(expectedIssuerCurve);
}
/**
* @param id
* @return first lookup value found for <code>id</code> or null
*/
public LookupValue getById(final Object id)
{
final ImmutableList<LookupValue> values = valuesById.get(normalizeId(id));
return values.isEmpty() ? null : values.get(0);
}
@Override
public void run(Path workdir, ImmutableList<String> sourceRefs)
throws RepoException, IOException, ValidationException {
if (sourceRefs.size() > 1) {
throw new CommandLineException(
String.format(
"Workflow does not support multiple source_ref arguments yet: %s",
ImmutableList.copyOf(sourceRefs)));
}
@Nullable
String sourceRef = sourceRefs.size() == 1 ? sourceRefs.get(0) : null;
validateFlags();
try (ProfilerTask ignore = profiler().start("run/" + name)) {
console.progress("Getting last revision: "
+ "Resolving " + ((sourceRef == null) ? "origin reference" : sourceRef));
O resolvedRef = generalOptions.repoTask("origin.resolve_source_ref",
() -> origin.resolve(sourceRef));
logger.log(Level.INFO, String.format(
"Running Copybara for workflow '%s' and ref '%s': %s",
name, resolvedRef.asString(),
this.toString()));
logger.log(Level.INFO, String.format("Using working directory : %s", workdir));
ImmutableList.Builder<DestinationEffect> allEffects = ImmutableList.builder();
WorkflowRunHelper<O, D> helper = newRunHelper(workdir, resolvedRef, sourceRef,
event -> {
allEffects.addAll(event.getDestinationEffects());
eventMonitor().onChangeMigrationFinished(event);
});
try (ProfilerTask ignored = profiler().start(mode.toString().toLowerCase())) {
mode.run(helper);
} finally {
if (!getGeneralOptions().dryRunMode) {
try (ProfilerTask ignored = profiler().start("after_all_migration")) {
ImmutableList<DestinationEffect> effects = allEffects.build();
ImmutableList<DestinationEffect> resultEffects = runHooks(
effects,
getAfterAllMigrationActions(),
// Only do this once for all the actions
memoized(c -> helper.getOriginReader().getFeedbackEndPoint(c)),
// Only do this once for all the actions
memoized(c -> helper.getDestinationWriter().getFeedbackEndPoint(c)),
resolvedRef);
if (effects.size() != resultEffects.size()) {
console.warn("Effects where created in after_all_migrations, but they are ignored.");
}
}
}
}
}
}
/**
* Asks the Skyframe evaluator to build the value for BuildConfigurationCollection and returns the
* result.
*/
// TODO(ulfjack): Remove this legacy method after switching to the Skyframe-based implementation.
public BuildConfigurationCollection createConfigurations(
ExtendedEventHandler eventHandler,
BuildOptions buildOptions,
Set<String> multiCpu,
boolean keepGoing)
throws InvalidConfigurationException {
if (configuredTargetProgress != null) {
configuredTargetProgress.reset();
}
ImmutableList<BuildConfiguration> topLevelTargetConfigs =
getConfigurations(
eventHandler,
PrepareAnalysisPhaseFunction.getTopLevelBuildOptions(buildOptions, multiCpu),
buildOptions,
keepGoing);
BuildConfiguration firstTargetConfig = topLevelTargetConfigs.get(0);
BuildOptions targetOptions = firstTargetConfig.getOptions();
BuildOptionsView hostTransitionOptionsView =
new BuildOptionsView(
firstTargetConfig.getOptions(), HostTransition.INSTANCE.requiresOptionFragments());
BuildOptions hostOptions =
targetOptions.get(CoreOptions.class).useDistinctHostConfiguration
? HostTransition.INSTANCE.patch(hostTransitionOptionsView, eventHandler)
: targetOptions;
BuildConfiguration hostConfig = getConfiguration(eventHandler, hostOptions, keepGoing);
// TODO(gregce): cache invalid option errors in BuildConfigurationFunction, then use a dedicated
// accessor (i.e. not the event handler) to trigger the exception below.
ErrorSensingEventHandler nosyEventHandler = new ErrorSensingEventHandler(eventHandler);
topLevelTargetConfigs.forEach(config -> config.reportInvalidOptions(nosyEventHandler));
if (nosyEventHandler.hasErrors()) {
throw new InvalidConfigurationException("Build options are invalid");
}
return new BuildConfigurationCollection(topLevelTargetConfigs, hostConfig);
}
private void checkProvidedConverter(
VariableElement optionField,
ImmutableList<TypeMirror> acceptedConverterReturnTypes,
TypeElement converterElement)
throws OptionProcessorException {
if (converterElement.getModifiers().contains(Modifier.ABSTRACT)) {
throw new OptionProcessorException(
optionField, "The converter type %s must be a concrete type", converterElement.asType());
}
DeclaredType converterType = (DeclaredType) converterElement.asType();
// Unfortunately, for provided classes, we do not have access to the compiled convert
// method at this time, and cannot check that the default value is parseable. We will
// instead check that T of Converter<T> matches the option's type, but this is all we can
// do.
List<ExecutableElement> methodList =
elementUtils.getAllMembers(converterElement).stream()
.filter(element -> element.getKind() == ElementKind.METHOD)
.map(methodElement -> (ExecutableElement) methodElement)
.filter(methodElement -> methodElement.getSimpleName().contentEquals("convert"))
.filter(
methodElement ->
methodElement.getParameters().size() == 1
&& typeUtils.isSameType(
methodElement.getParameters().get(0).asType(),
elementUtils.getTypeElement(String.class.getCanonicalName()).asType()))
.collect(Collectors.toList());
// Check that there is just the one method
if (methodList.size() != 1) {
throw new OptionProcessorException(
optionField,
"Converter %s has methods 'convert(String)': %s",
converterElement,
methodList.stream().map(Object::toString).collect(Collectors.joining(", ")));
}
ExecutableType convertMethodType =
(ExecutableType) typeUtils.asMemberOf(converterType, methodList.get(0));
TypeMirror convertMethodResultType = convertMethodType.getReturnType();
// Check that the converter's return type is in the accepted list.
for (TypeMirror acceptedConverterReturnType : acceptedConverterReturnTypes) {
if (typeUtils.isAssignable(convertMethodResultType, acceptedConverterReturnType)) {
return; // This one passes the test.
}
}
throw new OptionProcessorException(
optionField,
"Type of field (%s) must be assignable from the converter's return type (%s)",
acceptedConverterReturnTypes.get(0),
convertMethodResultType);
}