blob: 3f1342ad77dd40983ba57915a1f959fa49e61615 (
plain)
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
107
108
109
110
111
112
113
114
115
116
117
|
// 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.engine;
import com.google.devtools.build.lib.query2.engine.QueryEnvironment.TargetAccessor;
/**
* A predicate for targets included in the visibility list of a rule.
*
* <p>A rule's visibility is described by a set of {@link QueryVisibility}. Each element
* in the set corresponds to an entry in the rule's visibility attribute, or an entry in the
* packages attribute of an included package_group.
*/
public abstract class QueryVisibility<T> {
/** Returns true if the visibility specification includes the given target's package. */
public abstract boolean contains(T target);
/** Global visibility. */
@SuppressWarnings("unchecked") // Safe covariant cast.
public static <T> QueryVisibility<T> everything() {
return (QueryVisibility<T>) (Object) EVERYTHING;
}
private static final QueryVisibility<?> EVERYTHING = new QueryVisibility<Object>() {
@Override
public boolean contains(Object target) {
return true;
}
@Override
public String toString() {
return "QueryVisibility(//visibility:public)";
}
};
/**
* Empty visibility.
*
* <p>This is useful as a sentinel to indicate that a package specification could be parsed into
* a {@link QueryVisibility}. Same-package visibility is handled separately by
* {@link VisibleFunction}.
*/
@SuppressWarnings("unchecked") // Safe covariant cast.
public static <T> QueryVisibility<T> nothing() {
return (QueryVisibility<T>) (Object) NOTHING;
}
private static final QueryVisibility<?> NOTHING = new QueryVisibility<Object>() {
@Override
public boolean contains(Object target) {
return false;
}
@Override
public String toString() {
return "QueryVisibility(//visibility:private)";
}
};
/**
* Same-package visibility.
*
* <p>Targets are always visible to other targets in the same package. Additionally, targets
* under java/ are always visible to the corresponding package in javatests/.
*/
public static <T> QueryVisibility<T> samePackage(T from, TargetAccessor<T> accessor) {
return new SamePackageVisibility<>(from, accessor);
}
private static final class SamePackageVisibility<T> extends QueryVisibility<T> {
private static final String JAVA_PREFIX = "java/";
private static final String JAVATESTS_PREFIX = "javatests/";
private final String packageName;
private final TargetAccessor<T> accessor;
public SamePackageVisibility(T target, TargetAccessor<T> accessor) {
this.packageName = accessor.getPackage(target);
this.accessor = accessor;
}
@Override
public boolean contains(T target) {
String other = accessor.getPackage(target);
if (packageName.equals(other)) {
return true;
}
// packages in java/ are always visible from the corresponding package in javatests/
if (other.startsWith(JAVATESTS_PREFIX)
&& packageName.equals(JAVA_PREFIX + other.substring(JAVATESTS_PREFIX.length()))) {
return true;
}
return false;
}
@Override
public String toString() {
return String.format("QueryVisibility(samePackage=%s)", "<PACKAGE>");
}
}
}
|