1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
// Copyright 2016 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.analysis;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
/** A provider that gives information about the aliases a rule was resolved through. */
@AutoCodec
@Immutable
public final class AliasProvider implements TransitiveInfoProvider {
// We don't expect long alias chains, so it's better to have a list instead of a nested set
private final ImmutableList<Label> aliasChain;
public AliasProvider(ImmutableList<Label> aliasChain) {
Preconditions.checkState(!aliasChain.isEmpty());
this.aliasChain = aliasChain;
}
public static AliasProvider fromAliasRule(Label label, ConfiguredTarget actual) {
ImmutableList.Builder<Label> chain = ImmutableList.builder();
chain.add(label);
AliasProvider dep = actual.getProvider(AliasProvider.class);
if (dep != null) {
chain.addAll(dep.getAliasChain());
}
return new AliasProvider(chain.build());
}
/**
* Returns the label by which it was referred to in the BUILD file.
*
* <p>For non-alias rules, it's the label of the rule itself, for alias rules, it's the label of
* the alias rule.
*/
public static Label getDependencyLabel(TransitiveInfoCollection dep) {
AliasProvider aliasProvider = dep.getProvider(AliasProvider.class);
return aliasProvider != null
? aliasProvider.getAliasChain().get(0)
: dep.getLabel();
}
/**
* Returns the list of aliases from top to bottom (i.e. the last alias depends on the actual
* resolved target and the first alias is the one that was in the attribute of the rule currently
* being analyzed)
*/
public ImmutableList<Label> getAliasChain() {
return aliasChain;
}
/** The way {@link #describeTargetWithAliases(ConfiguredTargetAndData, TargetMode) reports the
* kind of a target. */
public enum TargetMode {
WITH_KIND, // Specify the kind of the target
WITHOUT_KIND, // Only say "target"
}
/**
* Prints a nice description of a target.
*
* Also adds the aliases it was reached through, if any.
*
* @param target the target to describe
* @param targetMode how to express the kind of the target
* @return
*/
public static String describeTargetWithAliases(
ConfiguredTargetAndData target, TargetMode targetMode) {
String kind = targetMode == TargetMode.WITH_KIND
? target.getTarget().getTargetKind() : "target";
AliasProvider aliasProvider = target.getConfiguredTarget().getProvider(AliasProvider.class);
if (aliasProvider == null) {
return kind + " '" + target.getTarget().getLabel() + "'";
}
ImmutableList<Label> aliasChain = aliasProvider.getAliasChain();
StringBuilder result = new StringBuilder();
result.append("alias '" + aliasChain.get(0) + "'");
result.append(" referring to " + kind + " '" + target.getTarget().getLabel() + "'");
if (aliasChain.size() > 1) {
result.append(" through '"
+ Joiner.on("' -> '").join(aliasChain.subList(1, aliasChain.size()))
+ "'");
}
return result.toString();
}
}
|