下面列出了com.google.common.collect.ImmutableList#size ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public Supplier<Multimap<Path, Path>> getOutputToInputsMapSupplier(
Path secondaryOutputDir, Path additionalOutputDir) {
return () -> {
Preconditions.checkState(
outputFiles != null,
"SplitZipStep must complete successfully before listing its outputs.");
ImmutableMultimap.Builder<Path, Path> builder = ImmutableMultimap.builder();
for (APKModule dexStore : outputFiles.keySet()) {
Path storeRoot;
if (dexStore.getName().equals(SECONDARY_DEX_ID)) {
storeRoot = secondaryOutputDir;
} else {
storeRoot = additionalOutputDir.resolve(dexStore.getName());
}
ImmutableList<Path> outputList = outputFiles.get(dexStore).asList();
for (int i = 0; i < outputList.size(); i++) {
String dexName = dexSplitMode.getDexStore().fileNameForSecondary(dexStore, i);
Path outputDexPath = storeRoot.resolve(dexName);
builder.put(outputDexPath, outputList.get(i));
}
}
return builder.build();
};
}
/**
* Gets a {@link Player} based on their display name.
* @param displayName The player's display name.
* @param table The table of {@link Hiscores}.
* @return An {@link Optional} containing the {@link Player}, or {@link Optional#empty()} if no {@link Player} was found with that name.
* @throws IOException If an I/O error occurs.
* @see <a href="https://runescape.wiki/w/Application_programming_interface#Hiscores_Lite">Hiscores Lite</a>
* @see <a href="https://runescape.wiki/w/Application_programming_interface#Ironman_Lite">Ironman Hiscores Lite</a>
* @see <a href="https://runescape.wiki/w/Application_programming_interface#Hardcore_Ironman_Lite">Hardcore Ironman Hiscores Lite</a>
*/
public Optional<Player> playerInformation(String displayName, HiscoreTable table) throws IOException {
Preconditions.checkNotNull(displayName);
Preconditions.checkNotNull(table);
String escapedName = NAME_SPACER.matcher(displayName).replaceAll("+");
String url = String.format(PLAYER_INFORMATION_URL_FORMAT, table.getName(), escapedName);
ImmutableList<CSVRecord> records = client.fromCSV(url);
ImmutableList<String> skillNames = table.getSkillNames();
ImmutableList<String> activityNames = table.getActivityNames();
if (records.size() >= (skillNames.size() + activityNames.size())) {
ImmutableMap<String, Skill> skills = readSkills(records, skillNames);
ImmutableMap<String, HiscoreActivity> activities = readActivities(records, skillNames, activityNames);
return Optional.of(new Player(skills, activities));
} else {
return Optional.empty();
}
}
/**
* Returns formatted string describing {@code problems} by removing similar problems per artifact.
*/
public static String formatProblems(Iterable<ArtifactProblem> problems) {
ImmutableListMultimap<Artifact, ArtifactProblem> artifactToProblems =
Multimaps.index(problems, ArtifactProblem::getArtifact);
StringBuilder output = new StringBuilder();
for (Artifact artifact : artifactToProblems.keySet()) {
ImmutableList<ArtifactProblem> artifactProblems = artifactToProblems.get(artifact);
int otherCount = artifactProblems.size() - 1;
verify(otherCount >= 0, "artifactToProblems should have at least one value for one key");
ArtifactProblem firstProblem = Iterables.getFirst(artifactProblems, null);
output.append(firstProblem);
if (otherCount == 1) {
output.append(" and a problem on the same artifact.");
} else if (otherCount > 1) {
output.append(" and " + otherCount + " problems on the same artifact.");
}
output.append("\n");
}
return output.toString();
}
/**
* Returns the <meta-data> XML element with the given "android:name" value if present.
*
* <p>Throws an {@link ValidationException} if there is more than one meta-data element with this
* name.
*/
private Optional<XmlProtoElement> getMetadataElement(String name) {
ImmutableList<XmlProtoElement> metadataElements =
getMetadataElements()
.filter(
metadataElement ->
metadataElement
.getAndroidAttribute(NAME_RESOURCE_ID)
.map(XmlProtoAttribute::getValueAsString)
.orElse("")
.equals(name))
.collect(toImmutableList());
switch (metadataElements.size()) {
case 0:
return Optional.empty();
case 1:
return Optional.of(metadataElements.get(0));
default:
throw InvalidBundleException.builder()
.withUserMessage(
"Found multiple <meta-data> elements for key '%s', expected at most one.", name)
.build();
}
}
public void test() {
for (int groupNumber = 0; groupNumber < groups.size(); groupNumber++) {
ImmutableList<T> group = groups.get(groupNumber);
for (int itemNumber = 0; itemNumber < group.size(); itemNumber++) {
// check related items in same group
for (int relatedItemNumber = 0; relatedItemNumber < group.size(); relatedItemNumber++) {
if (itemNumber != relatedItemNumber) {
assertRelated(groupNumber, itemNumber, relatedItemNumber);
}
}
// check unrelated items in all other groups
for (int unrelatedGroupNumber = 0; unrelatedGroupNumber < groups.size(); unrelatedGroupNumber++) {
if (groupNumber != unrelatedGroupNumber) {
ImmutableList<T> unrelatedGroup = groups.get(unrelatedGroupNumber);
for (int unrelatedItemNumber = 0; unrelatedItemNumber < unrelatedGroup
.size(); unrelatedItemNumber++) {
assertUnrelated(groupNumber, itemNumber, unrelatedGroupNumber, unrelatedItemNumber);
}
}
}
}
}
}
private <T extends Interceptor> @NotNull ImmutableList<T> addInterceptor(
final @NotNull ImmutableList<T> interceptors, final @NotNull T interceptor) {
if (interceptors.isEmpty()) {
return ImmutableList.of(interceptor);
}
final int priority = getExtensionPriority(interceptor);
int low = 0;
int high = interceptors.size() - 1;
while (low <= high) {
final int mid = low + high >>> 1;
final T midInterceptor = interceptors.get(mid);
final int midPriority = getExtensionPriority(midInterceptor);
if (midPriority >= priority) {
if (midPriority == priority && midInterceptor == interceptor) {
return interceptors;
}
low = mid + 1;
} else {
high = mid - 1;
}
}
final ImmutableList.Builder<T> builder = ImmutableList.builderWithExpectedSize(interceptors.size() + 1);
for (int i = 0; i < low; i++) {
builder.add(interceptors.get(i));
}
builder.add(interceptor);
for (int i = low; i < interceptors.size(); i++) {
builder.add(interceptors.get(i));
}
return builder.build();
}
/**
* Creates an instance, specifying the headers and row.
* <p>
* See {@link CsvFile}.
*
* @param headers the headers
* @param fields the fields
*/
private CsvRow(ImmutableList<String> headers, int lineNumber, ImmutableList<String> fields) {
this.headers = headers;
// need to allow duplicate headers and only store the first instance
Map<String, Integer> searchHeaders = new HashMap<>();
for (int i = 0; i < headers.size(); i++) {
String searchHeader = headers.get(i).toLowerCase(Locale.ENGLISH);
searchHeaders.putIfAbsent(searchHeader, i);
}
this.searchHeaders = ImmutableMap.copyOf(searchHeaders);
this.lineNumber = lineNumber;
this.fields = fields;
}
/**
* Adds a new element of type nodeType with a specific keyValue if the element is absent in this
* document. Will also add attributes expressed through key value pairs.
*
* @param actionRecorder to records creation actions.
* @param nodeType the node type to crete
* @param keyValue the optional key for the element.
* @param attributes the optional array of key value pairs for extra element attribute.
* @return the Xml element whether it was created or existed or {@link Optional#absent()} if
* it does not exist in this document.
*/
private Optional<Element> addIfAbsent(
@NonNull ActionRecorder actionRecorder,
@NonNull ManifestModel.NodeTypes nodeType,
@Nullable String keyValue,
@Nullable String reason,
@Nullable Pair<String, String>... attributes) {
Optional<XmlElement> xmlElementOptional = getByTypeAndKey(nodeType, keyValue);
if (xmlElementOptional.isPresent()) {
return Optional.absent();
}
Element elementNS = getXml()
.createElementNS(SdkConstants.ANDROID_URI, "android:" + nodeType.toXmlName());
ImmutableList<String> keyAttributesNames = nodeType.getNodeKeyResolver()
.getKeyAttributesNames();
if (keyAttributesNames.size() == 1) {
elementNS.setAttributeNS(
SdkConstants.ANDROID_URI, "android:" + keyAttributesNames.get(0), keyValue);
}
if (attributes != null) {
for (Pair<String, String> attribute : attributes) {
elementNS.setAttributeNS(
SdkConstants.ANDROID_URI, "android:" + attribute.getFirst(),
attribute.getSecond());
}
}
// record creation.
XmlElement xmlElement = new XmlElement(elementNS, this);
actionRecorder.recordImpliedNodeAction(xmlElement, reason);
getRootNode().getXml().appendChild(elementNS);
return Optional.of(elementNS);
}
public static PBXGroup assertHasSubgroupAndReturnIt(PBXGroup group, String subgroupName) {
ImmutableList<PBXGroup> candidates =
FluentIterable.from(group.getChildren())
.filter(input -> input.getName().equals(subgroupName))
.filter(PBXGroup.class)
.toList();
if (candidates.size() != 1) {
fail("Could not find a unique subgroup by its name");
}
return candidates.get(0);
}
@Override
public long remove(Type type, String value) throws MailQueueException {
ImmutableList<MemoryMailQueueItem> toBeRemoved = mailItems.stream()
.filter(item -> shouldRemove(item, type, value))
.collect(Guavate.toImmutableList());
toBeRemoved.forEach(mailItems::remove);
return toBeRemoved.size();
}
private static MultiAbi buildMultiAbi(String fileName) {
ImmutableList<String> tokens = ImmutableList.copyOf(ABI_SPLITTER.splitToList(fileName));
int nAbis = tokens.size() - 1;
checkState(tokens.get(nAbis).equals("img"), "File under 'apex/' does not have suffix 'img'");
return MultiAbi.newBuilder()
.addAllAbi(
tokens.stream()
.limit(nAbis)
.map(token -> checkAbiName(token, fileName))
.collect(toImmutableList()))
.build();
}
/**
* Calculates the price of the bond future product.
* <p>
* The price of the product is the price on the valuation date.
* <p>
* Strata uses <i>decimal prices</i> for bond futures. This is coherent with the pricing of {@link FixedCouponBond}.
* For example, a price of 99.32% is represented in Strata by 0.9932.
*
* @param future the future
* @param discountingProvider the discounting provider
* @return the price of the product, in decimal form
*/
public double price(ResolvedBondFuture future, LegalEntityDiscountingProvider discountingProvider) {
ImmutableList<ResolvedFixedCouponBond> basket = future.getDeliveryBasket();
int size = basket.size();
double[] priceBonds = new double[size];
for (int i = 0; i < size; ++i) {
ResolvedFixedCouponBond bond = basket.get(i);
double dirtyPrice = bondPricer.dirtyPriceFromCurves(bond, discountingProvider, future.getLastDeliveryDate());
priceBonds[i] = bondPricer.cleanPriceFromDirtyPrice(
bond, future.getLastDeliveryDate(), dirtyPrice) / future.getConversionFactors().get(i);
}
return Doubles.min(priceBonds);
}
@Test
public void testPriorityQueueOrdering() {
PriorityQueue<SamzaResourceRequest> pq = new PriorityQueue<>();
Instant now = Instant.now();
ImmutableList<SamzaResourceRequest> expectedOrder = ImmutableList.of(
createRequestForActive(now.minusSeconds(120)),
createRequestForActive(now),
createRequestForActive(now.plusSeconds(120)),
createRequestForActive(now.plusSeconds(240)),
createRequestForStandby(now.minusSeconds(120)),
createRequestForStandby(now),
createRequestForStandby(now.plusSeconds(120)),
createRequestForStandby(now.plusSeconds(240)));
SamzaResourceRequest[] copyExpectedOrder = new SamzaResourceRequest[expectedOrder.size()];
copyExpectedOrder = expectedOrder.toArray(copyExpectedOrder);
List<SamzaResourceRequest> shuffled = Arrays.asList(copyExpectedOrder);
Collections.shuffle(shuffled, new Random(Instant.now().toEpochMilli()));
pq.addAll(shuffled);
ArrayList priorityQueueOrder = new ArrayList();
for (int i = 0; i < expectedOrder.size(); ++i) {
priorityQueueOrder.add(pq.poll());
}
assertEquals(expectedOrder, priorityQueueOrder);
}
/**
* Checks if the command line generated for the build rule contains the pch-inclusion directive.
*
* <p>This serves as an indicator that the file is being compiled with PCH enabled.
*/
private static boolean commandLineContainsPchFlag(
BuildContext context,
CxxPreprocessAndCompile rule,
CxxToolProvider.Type toolType,
String headerFilename) {
ImmutableList<String> flags = rule.makeMainStep(context, false).getCommand();
switch (toolType) {
case CLANG:
// Clang uses "-include-pch somefilename.h.gch"
for (int i = 0; i + 1 < flags.size(); i++) {
if (flags.get(i).equals("-include-pch") && flags.get(i + 1).endsWith(".h.gch")) {
return true;
}
}
break;
case GCC:
// For GCC we'd use: "-include sometargetname#someflavor-cxx-hexdigitsofhash.h",
// i.e., it's the "-include" flag like in the prefix header case, but auto-gen-filename.
for (int i = 0; i + 1 < flags.size(); i++) {
if (flags.get(i).equals("-include")
&& !flags.get(i + 1).endsWith("/" + headerFilename)
&& !flags.get(i + 1).equals(headerFilename)) {
return true;
}
}
break;
case WINDOWS:
// TODO(steveo): windows support in the near future.
// (This case is not hit; parameters at top of this test class don't include WINDOWS.)
throw new IllegalStateException();
}
return false;
}
private ExecutableElement selectInstantiator(TypeElement encodedType)
throws SerializationProcessingFailedException {
List<ExecutableElement> constructors =
ElementFilter.constructorsIn(encodedType.getEnclosedElements());
ArrayList<ExecutableElement> factoryMethodsBuilder = new ArrayList<>();
for (ExecutableElement element : ElementFilter.methodsIn(encodedType.getEnclosedElements())) {
if (AutoCodecProcessor.hasInstantiatorAnnotation(element)) {
verifyFactoryMethod(encodedType, element);
factoryMethodsBuilder.add(element);
}
}
ImmutableList<ExecutableElement> markedInstantiators =
Stream.concat(
constructors.stream().filter(AutoCodecProcessor::hasInstantiatorAnnotation),
factoryMethodsBuilder.stream())
.collect(toImmutableList());
if (markedInstantiators.isEmpty()) {
// If nothing is marked, see if there is a unique constructor.
if (constructors.size() > 1) {
throw new SerializationProcessingFailedException(
encodedType,
"%s has multiple constructors but no Instantiator annotation.",
encodedType.getQualifiedName());
}
// In Java, every class has at least one constructor, so this never fails.
return constructors.get(0);
}
if (markedInstantiators.size() == 1) {
return markedInstantiators.get(0);
}
throw new SerializationProcessingFailedException(
encodedType, "%s has multiple Instantiator annotations.", encodedType.getQualifiedName());
}
/**
* Deserialize an HD Key.
* @param parent The parent node in the given key's deterministic hierarchy.
*/
public static DeterministicKey deserialize(NetworkParameters params, byte[] serializedKey, @Nullable DeterministicKey parent) {
ByteBuffer buffer = ByteBuffer.wrap(serializedKey);
int header = buffer.getInt();
if (header != params.getBip32HeaderPriv() && header != params.getBip32HeaderPub())
throw new IllegalArgumentException("Unknown header bytes: " + toBase58(serializedKey).substring(0, 4));
boolean pub = header == params.getBip32HeaderPub();
int depth = buffer.get() & 0xFF; // convert signed byte to positive int since depth cannot be negative
final int parentFingerprint = buffer.getInt();
final int i = buffer.getInt();
final ChildNumber childNumber = new ChildNumber(i);
ImmutableList<ChildNumber> path;
if (parent != null) {
if (parentFingerprint == 0)
throw new IllegalArgumentException("Parent was provided but this key doesn't have one");
if (parent.getFingerprint() != parentFingerprint)
throw new IllegalArgumentException("Parent fingerprints don't match");
path = HDUtils.append(parent.getPath(), childNumber);
if (path.size() != depth)
throw new IllegalArgumentException("Depth does not match");
} else {
if (depth >= 1)
// We have been given a key that is not a root key, yet we lack the object representing the parent.
// This can happen when deserializing an account key for a watching wallet. In this case, we assume that
// the client wants to conceal the key's position in the hierarchy. The path is truncated at the
// parent's node.
path = ImmutableList.of(childNumber);
else path = ImmutableList.of();
}
byte[] chainCode = new byte[32];
buffer.get(chainCode);
byte[] data = new byte[33];
buffer.get(data);
checkArgument(!buffer.hasRemaining(), "Found unexpected data in key");
if (pub) {
return new DeterministicKey(path, chainCode, new LazyECPoint(ECKey.CURVE.getCurve(), data), parent, depth, parentFingerprint);
} else {
return new DeterministicKey(path, chainCode, new BigInteger(1, data), parent, depth, parentFingerprint);
}
}
@Override
public void report(
ReportType type,
Message message1,
Message message2,
ImmutableList<SpecificField> fieldPath) {
try {
if ((type == ReportType.MODIFIED) && !reportModifiedAggregates) {
SpecificField specificField = Iterables.getLast(fieldPath);
if (specificField.getField() == null) {
if (specificField.getUnknown().getFieldType() == UnknownFieldType.GROUP) {
// Any changes to the subfields have already been printed.
return;
}
} else if (specificField.getField().getJavaType() == JavaType.MESSAGE) {
// Any changes to the subfields have already been printed.
return;
}
}
String tentativeNewline = "";
if (fieldPath.size() == 1) {
tentativeNewline = "\n";
}
output.append(type.name().toLowerCase()).append(": ");
switch (type) {
case ADDED:
appendPath(fieldPath, false);
output.append(": ");
appendValue(message2, fieldPath, false);
break;
case DELETED:
appendPath(fieldPath, true);
output.append(": ");
appendValue(message1, fieldPath, true);
break;
case IGNORED:
appendPath(fieldPath, false);
break;
case MOVED:
appendPath(fieldPath, true);
output.append(" -> ");
appendPath(fieldPath, false);
output.append(" : ");
appendValue(message1, fieldPath, true);
break;
case MODIFIED:
appendPath(fieldPath, true);
if (checkPathChanged(fieldPath)) {
output.append(" -> ");
appendPath(fieldPath, false);
}
output.append(":" + tentativeNewline);
appendValue(message1, fieldPath, true);
output.append(" -> " + tentativeNewline);
appendValue(message2, fieldPath, false);
break;
case MATCHED:
appendPath(fieldPath, true);
if (checkPathChanged(fieldPath)) {
output.append(" -> ");
appendPath(fieldPath, false);
}
output.append(" : ");
appendValue(message1, fieldPath, true);
break;
default:
throw new RuntimeException("Unknown ReportType");
}
output.append("\n" + tentativeNewline);
} catch (IOException e) {
throw new StreamException(e);
}
}
ValidationReport<TypeElement> validate(TypeElement element, OptionsDescriptor options) {
ValidationReport.Builder<TypeElement> builder = ValidationReport.about(element);
if (element.getKind() != ElementKind.CLASS) {
builder.addError(ErrorMessages.PAPERPARCEL_ON_NON_CLASS);
}
if (element.getModifiers().contains(Modifier.ABSTRACT)) {
builder.addError(ErrorMessages.PAPERPARCEL_ON_ABSTRACT_CLASS);
}
if (!Utils.isParcelable(elements, types, element.asType())) {
builder.addError(ErrorMessages.PAPERPARCEL_ON_NON_PARCELABLE);
}
if (implementsAnnotation(elements, types, element)) {
builder.addError(ErrorMessages.PAPERPARCEL_ON_ANNOTATION);
}
ElementKind enclosingKind = element.getEnclosingElement().getKind();
if (enclosingKind.isClass() || enclosingKind.isInterface()) {
if (Visibility.ofElement(element) == Visibility.PRIVATE) {
builder.addError(ErrorMessages.PAPERPARCEL_ON_PRIVATE_CLASS);
}
if (!element.getModifiers().contains(Modifier.STATIC)) {
builder.addError(ErrorMessages.PAPERPARCEL_ON_NON_STATIC_INNER_CLASS);
}
}
if (options.excludeNonExposedFields()
&& options.exposeAnnotationNames().isEmpty()) {
builder.addError(ErrorMessages.NO_EXPOSE_ANNOTATIONS_DEFINED, element, options.mirror());
}
if (!Utils.isSingleton(types, element)) {
ImmutableList<ExecutableElement> constructors =
Utils.orderedConstructorsIn(element, options.reflectAnnotations());
if (constructors.size() == 0) {
builder.addError(ErrorMessages.PAPERPARCEL_NO_VISIBLE_CONSTRUCTOR);
}
ImmutableList<VariableElement> fields = Utils.getFieldsToParcel(element, options);
for (VariableElement field : fields) {
if (Utils.containsWildcards(field.asType())) {
builder.addError(ErrorMessages.WILDCARD_IN_FIELD_TYPE, field);
} else if (Utils.isRawType(field.asType())) {
builder.addError(ErrorMessages.FIELD_MISSING_TYPE_ARGUMENTS, field);
} else if (Utils.hasRecursiveTypeParameter(field.asType())) {
builder.addError(ErrorMessages.FIELD_TYPE_IS_RECURSIVE, field);
} else if (Utils.containsIntersection(field.asType())) {
builder.addError(ErrorMessages.FIELD_TYPE_IS_INTERSECTION_TYPE, field);
}
}
}
return builder.build();
}
@Test
public void correctToolFilesUsed() throws Exception {
scratch.file(
"a/BUILD",
"cc_toolchain_alias(name = 'a')",
"cc_library(name = 'l', srcs = ['l.c'])",
"cc_library(name = 'asm', srcs = ['a.s'])",
"cc_library(name = 'preprocessed-asm', srcs = ['a.S'])");
getAnalysisMock()
.ccSupport()
.setupCcToolchainConfig(
mockToolsConfig,
CcToolchainConfig.builder().withFeatures(CppRuleClasses.SUPPORTS_DYNAMIC_LINKER));
useConfiguration("--incompatible_use_specific_tool_files");
ConfiguredTarget target = getConfiguredTarget("//a:a");
CcToolchainProvider toolchainProvider =
(CcToolchainProvider) target.get(ToolchainInfo.PROVIDER);
// Check that the mock toolchain tool file sets are an antichain, so that our subset assertions
// below are meaningful.
ImmutableList<Set<Artifact>> fileGroups =
ImmutableList.of(
toolchainProvider.getArFiles().toSet(),
toolchainProvider.getLinkerFiles().toSet(),
toolchainProvider.getCompilerFiles().toSet(),
toolchainProvider.getAsFiles().toSet(),
toolchainProvider.getAllFiles().toSet());
for (int i = 0; i < fileGroups.size(); i++) {
assertThat(fileGroups.get(i)).isNotEmpty();
for (int j = 0; j < fileGroups.size(); j++) {
if (i == j) {
continue;
}
Set<Artifact> one = fileGroups.get(i);
Set<Artifact> two = fileGroups.get(j);
assertWithMessage(String.format("%s should not contain %s", one, two))
.that(one.containsAll(two))
.isFalse();
}
}
assertThat(
Sets.difference(
toolchainProvider.getArFiles().toSet(), toolchainProvider.getLinkerFiles().toSet()))
.isNotEmpty();
assertThat(
Sets.difference(
toolchainProvider.getLinkerFiles().toSet(), toolchainProvider.getArFiles().toSet()))
.isNotEmpty();
RuleConfiguredTarget libTarget = (RuleConfiguredTarget) getConfiguredTarget("//a:l");
Artifact staticLib =
getOutputGroup(libTarget, "archive").toList().stream()
.collect(MoreCollectors.onlyElement());
ActionAnalysisMetadata staticAction = getGeneratingAction(staticLib);
assertThat(staticAction.getInputs().toList())
.containsAtLeastElementsIn(toolchainProvider.getArFiles().toList());
Artifact dynamicLib =
getOutputGroup(libTarget, "dynamic_library").toList().stream()
.collect(MoreCollectors.onlyElement());
ActionAnalysisMetadata dynamicAction = getGeneratingAction(dynamicLib);
assertThat(dynamicAction.getInputs().toList())
.containsAtLeastElementsIn(toolchainProvider.getLinkerFiles().toList());
ActionAnalysisMetadata cCompileAction =
libTarget.getActions().stream()
.filter((a) -> a.getMnemonic().equals("CppCompile"))
.collect(MoreCollectors.onlyElement());
assertThat(cCompileAction.getInputs().toList())
.containsAtLeastElementsIn(toolchainProvider.getCompilerFiles().toList());
ActionAnalysisMetadata asmAction =
((RuleConfiguredTarget) getConfiguredTarget("//a:asm"))
.getActions().stream()
.filter((a) -> a.getMnemonic().equals("CppCompile"))
.collect(MoreCollectors.onlyElement());
assertThat(asmAction.getInputs().toList())
.containsAtLeastElementsIn(toolchainProvider.getAsFiles().toList());
ActionAnalysisMetadata preprocessedAsmAction =
((RuleConfiguredTarget) getConfiguredTarget("//a:preprocessed-asm"))
.getActions().stream()
.filter((a) -> a.getMnemonic().equals("CppCompile"))
.collect(MoreCollectors.onlyElement());
assertThat(preprocessedAsmAction.getInputs().toList())
.containsAtLeastElementsIn(toolchainProvider.getCompilerFiles().toList());
}
/**
* Creates the list of adjusted dates in the schedule.
* <p>
* The adjusted date list will contain at least two elements, the start date and end date.
* Between those dates will be the calculated periodic schedule.
* Each date will be a valid business day as per the appropriate business day adjustment.
* <p>
* The roll convention, stub convention and additional dates are all used to determine the schedule.
* If the roll convention is not present it will be defaulted from the stub convention, with 'None' as the default.
* If there are explicit stub dates then they will be used.
* If the stub convention is present, then it will be validated against the stub dates.
* If the stub convention and stub dates are not present, then no stubs are allowed.
* <p>
* There is special handling for pre-adjusted start dates to avoid creating incorrect stubs.
* If all the following conditions hold true, then the unadjusted start date is treated
* as being the day-of-month implied by the roll convention (the adjusted date is unaffected).
* <ul>
* <li>the {@code startDateBusinessDayAdjustment} property equals {@link BusinessDayAdjustment#NONE}
* or the roll convention is 'EOM'
* <li>the roll convention is numeric or 'EOM'
* <li>applying {@code businessDayAdjustment} to the day-of-month implied by the roll convention
* yields the specified start date
* </ul>
* <p>
* There is additional special handling for pre-adjusted first/last regular dates and the end date.
* If the following conditions hold true, then the unadjusted date is treated as being the
* day-of-month implied by the roll convention (the adjusted date is unaffected).
* <ul>
* <li>the roll convention is numeric or 'EOM'
* <li>applying {@code businessDayAdjustment} to the day-of-month implied by the roll convention
* yields the first/last regular date that was specified
* </ul>
*
* @return the schedule of dates adjusted to valid business days
* @param refData the reference data, used to find the holiday calendar
* @throws ScheduleException if the definition is invalid
*/
public ImmutableList<LocalDate> createAdjustedDates(ReferenceData refData) {
LocalDate unadjStart = calculatedUnadjustedStartDate(refData);
LocalDate unadjEnd = calculatedUnadjustedEndDate(refData);
LocalDate regularStart = calculatedFirstRegularStartDate(unadjStart, refData);
LocalDate regularEnd = calculatedLastRegularEndDate(unadjEnd, refData);
RollConvention rollConv = calculatedRollConvention(regularStart, regularEnd);
List<LocalDate> unadj = generateUnadjustedDates(unadjStart, regularStart, regularEnd, unadjEnd, rollConv);
List<LocalDate> adj = applyBusinessDayAdjustment(unadj, refData);
// ensure schedule is valid with no duplicated dates
ImmutableList<LocalDate> deduplicated = ImmutableSet.copyOf(adj).asList();
if (deduplicated.size() < adj.size()) {
throw new ScheduleException(
this,
"Schedule calculation resulted in duplicate adjusted dates {} from unadjusted dates {} using adjustment '{}'",
adj,
unadj,
businessDayAdjustment);
}
return deduplicated;
}