// Copyright 2015 The Bazel Authors. All rights reserved. // // 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.google.devtools.build.lib.query2; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.AggregatingAttributeMapper; import com.google.devtools.build.lib.packages.ConstantRuleVisibility; import com.google.devtools.build.lib.packages.PackageGroup; import com.google.devtools.build.lib.packages.PackageGroupsRuleVisibility; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.RuleVisibility; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.packages.TargetUtils; import com.google.devtools.build.lib.query2.engine.QueryEnvironment.TargetAccessor; import com.google.devtools.build.lib.query2.engine.QueryEnvironment.TargetNotFoundException; import com.google.devtools.build.lib.query2.engine.QueryException; import com.google.devtools.build.lib.query2.engine.QueryExpression; import com.google.devtools.build.lib.query2.engine.QueryVisibility; import com.google.devtools.build.lib.syntax.Type; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * Implementation of {@link TargetAccessor <Target>} that uses an * {@link AbstractBlazeQueryEnvironment <Target>} internally to report issues and resolve * targets. */ final class BlazeTargetAccessor implements TargetAccessor { private final AbstractBlazeQueryEnvironment queryEnvironment; BlazeTargetAccessor(AbstractBlazeQueryEnvironment queryEnvironment) { this.queryEnvironment = queryEnvironment; } @Override public String getTargetKind(Target target) { return target.getTargetKind(); } @Override public String getLabel(Target target) { return target.getLabel().toString(); } @Override public String getPackage(Target target) { return target.getPackage().getNameFragment().toString(); } @Override public List getLabelListAttr( QueryExpression caller, Target target, String attrName, String errorMsgPrefix) throws QueryException, InterruptedException { Preconditions.checkArgument(target instanceof Rule); List 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; } @Override public List getStringListAttr(Target target, String attrName) { return TargetUtils.getStringListAttr(target, attrName); } @Override public String getStringAttr(Target target, String attrName) { return TargetUtils.getStringAttr(target, attrName); } @Override public Iterable getAttrAsString(Target target, String attrName) { return TargetUtils.getAttrAsString(target, attrName); } @Override public boolean isRule(Target target) { return target instanceof Rule; } @Override public boolean isTestRule(Target target) { return TargetUtils.isTestRule(target); } @Override public boolean isTestSuite(Target target) { return TargetUtils.isTestSuiteRule(target); } @Override public Set> getVisibility(Target target) throws QueryException, InterruptedException { ImmutableSet.Builder> result = ImmutableSet.builder(); result.add(QueryVisibility.samePackage(target, this)); convertVisibility(result, target); return result.build(); } // CAUTION: keep in sync with ConfiguredTargetFactory#convertVisibility() private void convertVisibility( ImmutableSet.Builder> packageSpecifications, Target target) throws QueryException, InterruptedException { RuleVisibility ruleVisibility = target.getVisibility(); if (ruleVisibility instanceof ConstantRuleVisibility) { if (((ConstantRuleVisibility) ruleVisibility).isPubliclyVisible()) { packageSpecifications.add(QueryVisibility.everything()); } return; } else if (ruleVisibility instanceof PackageGroupsRuleVisibility) { PackageGroupsRuleVisibility packageGroupsVisibility = (PackageGroupsRuleVisibility) ruleVisibility; for (Label groupLabel : packageGroupsVisibility.getPackageGroups()) { try { convertGroupVisibility((PackageGroup) queryEnvironment.getTarget(groupLabel), packageSpecifications); } catch (TargetNotFoundException e) { throw new QueryException(e.getMessage()); } } packageSpecifications.add( new BlazeQueryVisibility(packageGroupsVisibility.getDirectPackages())); return; } else { throw new IllegalStateException("unknown visibility: " + ruleVisibility.getClass()); } } private void convertGroupVisibility( PackageGroup group, ImmutableSet.Builder> packageSpecifications) throws QueryException, TargetNotFoundException, InterruptedException { for (Label include : group.getIncludes()) { convertGroupVisibility((PackageGroup) queryEnvironment.getTarget(include), packageSpecifications); } packageSpecifications.add(new BlazeQueryVisibility(group.getPackageSpecifications())); } }