use of com.google.devtools.build.lib.packages.AggregatingAttributeMapper in project bazel by bazelbuild.
the class OutputFormatter method getPossibleAttributeValues.
/**
* Returns the possible values of the specified attribute in the specified rule. For simple
* attributes, this is a single value. For configurable and computed attributes, this may be a
* list of values. See {@link AggregatingAttributeMapper#getPossibleAttributeValues} for how the
* values are determined.
*
* <p>This applies an important optimization for label lists: instead of returning all possible
* values, it only returns possible <i>labels</i>. For example, given:
*
* <pre>
* select({
* ":c": ["//a:one", "//a:two"],
* ":d": ["//a:two"]
* })</pre>
*
* it returns:
*
* <pre>["//a:one", "//a:two"]</pre>
*
* which loses track of which label appears in which branch.
*
* <p>This avoids the memory overruns that can happen be iterating over every possible value
* for an <code>attr = select(...) + select(...) + select(...) + ...</code> expression. Query
* operations generally don't care about specific attribute values - they just care which labels
* are possible.
*/
protected static PossibleAttributeValues getPossibleAttributeValues(Rule rule, Attribute attr) throws InterruptedException {
AttributeValueSource source;
if (attr.getName().equals("visibility")) {
if (rule.isVisibilitySpecified()) {
source = AttributeValueSource.RULE;
} else if (rule.getPackage().isDefaultVisibilitySet()) {
source = AttributeValueSource.PACKAGE;
} else {
source = AttributeValueSource.DEFAULT;
}
} else {
source = rule.isAttributeValueExplicitlySpecified(attr) ? AttributeValueSource.RULE : AttributeValueSource.DEFAULT;
}
AggregatingAttributeMapper attributeMap = AggregatingAttributeMapper.of(rule);
if (attr.getType().equals(BuildType.LABEL_LIST) && attributeMap.isConfigurable(attr.getName())) {
// directly into Type.
return new PossibleAttributeValues(ImmutableList.<Object>of(attributeMap.getReachableLabels(attr.getName(), /*includeSelectKeys=*/
false)), source);
} else {
return new PossibleAttributeValues(attributeMap.getPossibleAttributeValues(rule, attr), source);
}
}
use of com.google.devtools.build.lib.packages.AggregatingAttributeMapper in project bazel by bazelbuild.
the class AggregatingAttributeMapperTest method testDuplicateCheckOnNullValues.
@Test
public void testDuplicateCheckOnNullValues() throws Exception {
if (getAnalysisMock().isThisBazel()) {
return;
}
Rule rule = scratchRule("x", "main", "java_binary(", " name = 'main',", " srcs = ['main.java'])");
AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule);
Attribute launcherAttribute = mapper.getAttributeDefinition("launcher");
assertNull(mapper.get(launcherAttribute.getName(), launcherAttribute.getType()));
assertThat(mapper.checkForDuplicateLabels(launcherAttribute)).containsExactlyElementsIn(ImmutableList.of());
}
use of com.google.devtools.build.lib.packages.AggregatingAttributeMapper in project bazel by bazelbuild.
the class AggregatingAttributeMapperTest method testGetReachableLabels.
@Test
public void testGetReachableLabels() throws Exception {
Rule rule = scratchRule("x", "main", "cc_binary(", " name = 'main',", " srcs = select({", " '//conditions:a': ['a.cc'],", " '//conditions:b': ['b.cc']})", " + ", " ['always.cc']", " + ", " select({", " '//conditions:c': ['c.cc'],", " '//conditions:d': ['d.cc'],", " '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': ['default.cc'],", " }))");
ImmutableList<Label> valueLabels = ImmutableList.of(Label.create("@//x", "a.cc"), Label.create("@//x", "b.cc"), Label.create("@//x", "always.cc"), Label.create("@//x", "c.cc"), Label.create("@//x", "d.cc"), Label.create("@//x", "default.cc"));
ImmutableList<Label> keyLabels = ImmutableList.of(Label.create("@//conditions", "a"), Label.create("@//conditions", "b"), Label.create("@//conditions", "c"), Label.create("@//conditions", "d"));
AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule);
assertThat(mapper.getReachableLabels("srcs", true)).containsExactlyElementsIn(Iterables.concat(valueLabels, keyLabels));
assertThat(mapper.getReachableLabels("srcs", false)).containsExactlyElementsIn(valueLabels);
}
use of com.google.devtools.build.lib.packages.AggregatingAttributeMapper in project bazel by bazelbuild.
the class BlazeTargetAccessor method getLabelListAttr.
@Override
public List<Target> getLabelListAttr(QueryExpression caller, Target target, String attrName, String errorMsgPrefix) throws QueryException, InterruptedException {
Preconditions.checkArgument(target instanceof Rule);
List<Target> result = new ArrayList<>();
Rule rule = (Rule) target;
AggregatingAttributeMapper attrMap = AggregatingAttributeMapper.of(rule);
Type<?> attrType = attrMap.getAttributeType(attrName);
if (attrType == null) {
// Return an empty list if the attribute isn't defined for this rule.
return ImmutableList.of();
}
for (Label label : attrMap.getReachableLabels(attrName, false)) {
try {
result.add(queryEnvironment.getTarget(label));
} catch (TargetNotFoundException e) {
queryEnvironment.reportBuildFileError(caller, errorMsgPrefix + e.getMessage());
}
}
return result;
}
use of com.google.devtools.build.lib.packages.AggregatingAttributeMapper in project bazel by bazelbuild.
the class LocalRepositoryLookupFunction method maybeCheckWorkspaceForRepository.
/**
* Checks whether the directory exists and is a workspace root. Returns {@link Optional#absent()}
* if Skyframe needs to re-run, {@link Optional#of(LocalRepositoryLookupValue)} otherwise.
*/
private Optional<LocalRepositoryLookupValue> maybeCheckWorkspaceForRepository(Environment env, final RootedPath directory) throws InterruptedException, LocalRepositoryLookupFunctionException {
// Look up the main WORKSPACE file by the external package, to find all repositories.
PackageLookupValue externalPackageLookupValue;
try {
externalPackageLookupValue = (PackageLookupValue) env.getValueOrThrow(PackageLookupValue.key(Label.EXTERNAL_PACKAGE_IDENTIFIER), BuildFileNotFoundException.class, InconsistentFilesystemException.class);
if (externalPackageLookupValue == null) {
return Optional.absent();
}
} catch (BuildFileNotFoundException e) {
throw new LocalRepositoryLookupFunctionException(new ErrorDeterminingRepositoryException("BuildFileNotFoundException while loading the //external package", e), Transience.PERSISTENT);
} catch (InconsistentFilesystemException e) {
throw new LocalRepositoryLookupFunctionException(new ErrorDeterminingRepositoryException("InconsistentFilesystemException while loading the //external package", e), Transience.PERSISTENT);
}
RootedPath workspacePath = externalPackageLookupValue.getRootedPath(Label.EXTERNAL_PACKAGE_IDENTIFIER);
SkyKey workspaceKey = WorkspaceFileValue.key(workspacePath);
do {
WorkspaceFileValue value;
try {
value = (WorkspaceFileValue) env.getValueOrThrow(workspaceKey, PackageFunctionException.class, NameConflictException.class);
if (value == null) {
return Optional.absent();
}
} catch (PackageFunctionException e) {
// TODO(jcater): When WFF is rewritten to not throw a PFE, update this.
throw new LocalRepositoryLookupFunctionException(new ErrorDeterminingRepositoryException("PackageFunctionException while loading the root WORKSPACE file", e), Transience.PERSISTENT);
} catch (NameConflictException e) {
throw new LocalRepositoryLookupFunctionException(new ErrorDeterminingRepositoryException("NameConflictException while loading the root WORKSPACE file", e), Transience.PERSISTENT);
}
Package externalPackage = value.getPackage();
if (externalPackage.containsErrors()) {
Event.replayEventsOn(env.getListener(), externalPackage.getEvents());
}
// Find all local_repository rules in the WORKSPACE, and check if any have a "path" attribute
// the same as the requested directory.
Iterable<Rule> localRepositories = externalPackage.getRulesMatchingRuleClass(LocalRepositoryRule.NAME);
Rule rule = Iterables.find(localRepositories, new Predicate<Rule>() {
@Override
public boolean apply(@Nullable Rule rule) {
AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule);
PathFragment pathAttr = new PathFragment(mapper.get("path", Type.STRING));
return directory.getRelativePath().equals(pathAttr);
}
}, null);
if (rule != null) {
try {
return Optional.of(LocalRepositoryLookupValue.success(RepositoryName.create("@" + rule.getName())));
} catch (LabelSyntaxException e) {
// validated.
throw new LocalRepositoryLookupFunctionException(new ErrorDeterminingRepositoryException("LabelSyntaxException while creating the repository name from the rule " + rule.getName(), e), Transience.PERSISTENT);
}
}
workspaceKey = value.next();
// TODO(bazel-team): This loop can be quadratic in the number of load() statements, consider
// rewriting or unrolling.
} while (workspaceKey != null);
return Optional.of(LocalRepositoryLookupValue.notFound());
}
Aggregations