Lift PackageArgument and default package arguments out of PackageFactory
PakcageArgument seems like a popular enough thing to live in its own top-level
java file. The default arguments (I think that's a fair term(?)) are unrelated
to PackageFactory enough to justify hiding away in their own class. The end
result is we can now see (many of) PackageFactory's instance members without
having to scroll (there are still some scattered elsewhere in the class).
Also moved PackageFactory.getVisibility -> PackageUtils.getVisibility in order
to avoid a benign but awkard circular dependency.
RELNOTES: None
PiperOrigin-RevId: 296337425
diff --git a/src/main/java/com/google/devtools/build/lib/packages/DefaultPackageArguments.java b/src/main/java/com/google/devtools/build/lib/packages/DefaultPackageArguments.java
new file mode 100644
index 0000000..7d4f639
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/packages/DefaultPackageArguments.java
@@ -0,0 +1,178 @@
+// Copyright 2020 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.packages;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.packages.License.DistributionType;
+import com.google.devtools.build.lib.syntax.EvalException;
+import java.util.List;
+import java.util.Set;
+
+/** Encapsulates the core, default set of {@link PackageArgument}s. */
+final class DefaultPackageArguments {
+
+ private DefaultPackageArguments() {}
+
+ /** Returns the default set of {@link PackageArgument}s. */
+ static ImmutableList<PackageArgument<?>> get() {
+ return ImmutableList.of(
+ new DefaultDeprecation(),
+ new DefaultDistribs(),
+ new DefaultApplicableLicenses(),
+ new DefaultLicenses(),
+ new DefaultTestOnly(),
+ new DefaultVisibility(),
+ new Features(),
+ new DefaultCompatibleWith(),
+ new DefaultRestrictedTo());
+ }
+
+ private static class DefaultVisibility extends PackageArgument<List<Label>> {
+ private DefaultVisibility() {
+ super("default_visibility", BuildType.LABEL_LIST);
+ }
+
+ @Override
+ protected void process(Package.Builder pkgBuilder, Location location,
+ List<Label> value) throws EvalException {
+ try {
+ pkgBuilder.setDefaultVisibility(
+ PackageUtils.getVisibility(pkgBuilder.getBuildFileLabel(), value));
+ } catch (EvalException e) {
+ throw new EvalException(location, e.getMessage());
+ }
+ }
+ }
+
+ private static class DefaultTestOnly extends PackageArgument<Boolean> {
+ private DefaultTestOnly() {
+ super("default_testonly", Type.BOOLEAN);
+ }
+
+ @Override
+ protected void process(Package.Builder pkgBuilder, Location location,
+ Boolean value) {
+ pkgBuilder.setDefaultTestonly(value);
+ }
+ }
+
+ private static class DefaultDeprecation extends PackageArgument<String> {
+ private DefaultDeprecation() {
+ super("default_deprecation", Type.STRING);
+ }
+
+ @Override
+ protected void process(Package.Builder pkgBuilder, Location location,
+ String value) {
+ pkgBuilder.setDefaultDeprecation(value);
+ }
+ }
+
+ private static class Features extends PackageArgument<List<String>> {
+ private Features() {
+ super("features", Type.STRING_LIST);
+ }
+
+ @Override
+ protected void process(Package.Builder pkgBuilder, Location location,
+ List<String> value) {
+ pkgBuilder.addFeatures(value);
+ }
+ }
+
+ /**
+ * Declares the package() attribute specifying the default value for {@link
+ * com.google.devtools.build.lib.packages.RuleClass#APPLICABLE_LICENSES_ATTR} when not explicitly
+ * specified.
+ */
+ private static class DefaultApplicableLicenses extends PackageArgument<List<Label>> {
+ private static final String DEFAULT_APPLICABLE_LICENSES_ATTRIBUTE =
+ "default_applicable_licenses";
+
+ private DefaultApplicableLicenses() {
+ super(DEFAULT_APPLICABLE_LICENSES_ATTRIBUTE, BuildType.LABEL_LIST);
+ }
+
+ @Override
+ protected void process(Package.Builder pkgBuilder, Location location, List<Label> value) {
+ pkgBuilder.setDefaultApplicableLicenses(
+ value, DEFAULT_APPLICABLE_LICENSES_ATTRIBUTE, location);
+ }
+ }
+
+ private static class DefaultLicenses extends PackageArgument<License> {
+ private DefaultLicenses() {
+ super("licenses", BuildType.LICENSE);
+ }
+
+ @Override
+ protected void process(Package.Builder pkgBuilder, Location location,
+ License value) {
+ pkgBuilder.setDefaultLicense(value);
+ }
+ }
+
+ private static class DefaultDistribs extends PackageArgument<Set<DistributionType>> {
+ private DefaultDistribs() {
+ super("distribs", BuildType.DISTRIBUTIONS);
+ }
+
+ @Override
+ protected void process(Package.Builder pkgBuilder, Location location,
+ Set<DistributionType> value) {
+ pkgBuilder.setDefaultDistribs(value);
+ }
+ }
+
+ /**
+ * Declares the package() attribute specifying the default value for {@link
+ * com.google.devtools.build.lib.packages.RuleClass#COMPATIBLE_ENVIRONMENT_ATTR} when not
+ * explicitly specified.
+ */
+ private static class DefaultCompatibleWith extends PackageArgument<List<Label>> {
+ private static final String DEFAULT_COMPATIBLE_WITH_ATTRIBUTE = "default_compatible_with";
+
+ private DefaultCompatibleWith() {
+ super(DEFAULT_COMPATIBLE_WITH_ATTRIBUTE, BuildType.LABEL_LIST);
+ }
+
+ @Override
+ protected void process(Package.Builder pkgBuilder, Location location,
+ List<Label> value) {
+ pkgBuilder.setDefaultCompatibleWith(value, DEFAULT_COMPATIBLE_WITH_ATTRIBUTE, location);
+ }
+ }
+
+ /**
+ * Declares the package() attribute specifying the default value for {@link
+ * com.google.devtools.build.lib.packages.RuleClass#RESTRICTED_ENVIRONMENT_ATTR} when not
+ * explicitly specified.
+ */
+ private static class DefaultRestrictedTo extends PackageArgument<List<Label>> {
+ private static final String DEFAULT_RESTRICTED_TO_ATTRIBUTE = "default_restricted_to";
+
+ private DefaultRestrictedTo() {
+ super(DEFAULT_RESTRICTED_TO_ATTRIBUTE, BuildType.LABEL_LIST);
+ }
+
+ @Override
+ protected void process(Package.Builder pkgBuilder, Location location,
+ List<Label> value) {
+ pkgBuilder.setDefaultRestrictedTo(value, DEFAULT_RESTRICTED_TO_ATTRIBUTE, location);
+ }
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageArgument.java b/src/main/java/com/google/devtools/build/lib/packages/PackageArgument.java
new file mode 100644
index 0000000..7c2c5ff
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageArgument.java
@@ -0,0 +1,57 @@
+// Copyright 2020 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.packages;
+
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.syntax.EvalException;
+
+/** Defines an argument to the {@code package()} function. */
+public abstract class PackageArgument<T> {
+ private final String name;
+ private final Type<T> type;
+
+ protected PackageArgument(String name, Type<T> type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ String getName() {
+ return name;
+ }
+
+ /**
+ * Converts an untyped argument to a typed one, then calls the user-provided {@link #process}.
+ *
+ * Note that the location is used not just for exceptions (for which null would do), but also for
+ * reporting events.
+ */
+ final void convertAndProcess(
+ Package.Builder pkgBuilder, Location location, Object value)
+ throws EvalException {
+ T typedValue = type.convert(value, "'package' argument", pkgBuilder.getBuildFileLabel());
+ process(pkgBuilder, location, typedValue);
+ }
+
+ /**
+ * Processes an argument.
+ *
+ * @param pkgBuilder the package builder to be mutated
+ * @param location the location of the {@code package} function for error reporting
+ * @param value the value of the argument. Typically passed to {@link Type#convert}
+ */
+ protected abstract void process(
+ Package.Builder pkgBuilder, Location location, T value)
+ throws EvalException;
+}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index 91526d4..036e1ee 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -32,7 +32,6 @@
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.events.StoredEventHandler;
import com.google.devtools.build.lib.packages.Globber.BadGlobException;
-import com.google.devtools.build.lib.packages.License.DistributionType;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.packages.RuleFactory.BuildLangTypedAttributeValuesMap;
import com.google.devtools.build.lib.syntax.Argument;
@@ -90,41 +89,8 @@
* Typically only one is needed per client application.
*/
public final class PackageFactory {
- /**
- * An argument to the {@code package()} function.
- */
- public abstract static class PackageArgument<T> {
- private final String name;
- private final Type<T> type;
- protected PackageArgument(String name, Type<T> type) {
- this.name = name;
- this.type = type;
- }
-
- public String getName() {
- return name;
- }
-
- // The location is used not just for exceptions (for which null would do),
- // but also for reporting events.
- private void convertAndProcess(Package.Builder pkgBuilder, Location location, Object value)
- throws EvalException {
- T typedValue = type.convert(value, "'package' argument", pkgBuilder.getBuildFileLabel());
- process(pkgBuilder, location, typedValue);
- }
-
- /**
- * Process an argument.
- *
- * @param pkgBuilder the package builder to be mutated
- * @param location the location of the {@code package} function for error reporting
- * @param value the value of the argument. Typically passed to {@link Type#convert}
- */
- protected abstract void process(
- Package.Builder pkgBuilder, Location location, T value)
- throws EvalException;
- }
+ private static final Logger logger = Logger.getLogger(PackageFactory.class.getName());
/** An extension to the global namespace of the BUILD language. */
// TODO(bazel-team): this is largely unrelated to syntax.StarlarkThread.Extension,
@@ -146,142 +112,6 @@
Iterable<PackageArgument<?>> getPackageArguments();
}
- private static class DefaultVisibility extends PackageArgument<List<Label>> {
- private DefaultVisibility() {
- super("default_visibility", BuildType.LABEL_LIST);
- }
-
- @Override
- protected void process(Package.Builder pkgBuilder, Location location,
- List<Label> value) throws EvalException{
- try {
- pkgBuilder.setDefaultVisibility(getVisibility(pkgBuilder.getBuildFileLabel(), value));
- } catch (EvalException e) {
- throw new EvalException(location, e.getMessage());
- }
- }
- }
-
- private static class DefaultTestOnly extends PackageArgument<Boolean> {
- private DefaultTestOnly() {
- super("default_testonly", Type.BOOLEAN);
- }
-
- @Override
- protected void process(Package.Builder pkgBuilder, Location location,
- Boolean value) {
- pkgBuilder.setDefaultTestonly(value);
- }
- }
-
- private static class DefaultDeprecation extends PackageArgument<String> {
- private DefaultDeprecation() {
- super("default_deprecation", Type.STRING);
- }
-
- @Override
- protected void process(Package.Builder pkgBuilder, Location location,
- String value) {
- pkgBuilder.setDefaultDeprecation(value);
- }
- }
-
- private static class Features extends PackageArgument<List<String>> {
- private Features() {
- super("features", Type.STRING_LIST);
- }
-
- @Override
- protected void process(Package.Builder pkgBuilder, Location location,
- List<String> value) {
- pkgBuilder.addFeatures(value);
- }
- }
-
- /**
- * Declares the package() attribute specifying the default value for {@link
- * com.google.devtools.build.lib.packages.RuleClass#APPLICABLE_LICENSES_ATTR} when not explicitly
- * specified.
- */
- private static class DefaultApplicableLicenses extends PackageArgument<List<Label>> {
- private static final String DEFAULT_APPLICABLE_LICENSES_ATTRIBUTE =
- "default_applicable_licenses";
-
- private DefaultApplicableLicenses() {
- super(DEFAULT_APPLICABLE_LICENSES_ATTRIBUTE, BuildType.LABEL_LIST);
- }
-
- @Override
- protected void process(Package.Builder pkgBuilder, Location location, List<Label> value) {
- pkgBuilder.setDefaultApplicableLicenses(
- value, DEFAULT_APPLICABLE_LICENSES_ATTRIBUTE, location);
- }
- }
-
- private static class DefaultLicenses extends PackageArgument<License> {
- private DefaultLicenses() {
- super("licenses", BuildType.LICENSE);
- }
-
- @Override
- protected void process(Package.Builder pkgBuilder, Location location,
- License value) {
- pkgBuilder.setDefaultLicense(value);
- }
- }
-
- private static class DefaultDistribs extends PackageArgument<Set<DistributionType>> {
- private DefaultDistribs() {
- super("distribs", BuildType.DISTRIBUTIONS);
- }
-
- @Override
- protected void process(Package.Builder pkgBuilder, Location location,
- Set<DistributionType> value) {
- pkgBuilder.setDefaultDistribs(value);
- }
- }
-
- /**
- * Declares the package() attribute specifying the default value for {@link
- * com.google.devtools.build.lib.packages.RuleClass#COMPATIBLE_ENVIRONMENT_ATTR} when not
- * explicitly specified.
- */
- private static class DefaultCompatibleWith extends PackageArgument<List<Label>> {
- private static final String DEFAULT_COMPATIBLE_WITH_ATTRIBUTE = "default_compatible_with";
-
- private DefaultCompatibleWith() {
- super(DEFAULT_COMPATIBLE_WITH_ATTRIBUTE, BuildType.LABEL_LIST);
- }
-
- @Override
- protected void process(Package.Builder pkgBuilder, Location location,
- List<Label> value) {
- pkgBuilder.setDefaultCompatibleWith(value, DEFAULT_COMPATIBLE_WITH_ATTRIBUTE, location);
- }
- }
-
- /**
- * Declares the package() attribute specifying the default value for {@link
- * com.google.devtools.build.lib.packages.RuleClass#RESTRICTED_ENVIRONMENT_ATTR} when not
- * explicitly specified.
- */
- private static class DefaultRestrictedTo extends PackageArgument<List<Label>> {
- private static final String DEFAULT_RESTRICTED_TO_ATTRIBUTE = "default_restricted_to";
-
- private DefaultRestrictedTo() {
- super(DEFAULT_RESTRICTED_TO_ATTRIBUTE, BuildType.LABEL_LIST);
- }
-
- @Override
- protected void process(Package.Builder pkgBuilder, Location location,
- List<Label> value) {
- pkgBuilder.setDefaultRestrictedTo(value, DEFAULT_RESTRICTED_TO_ATTRIBUTE, location);
- }
- }
-
- private static final Logger logger = Logger.getLogger(PackageFactory.class.getName());
-
private final RuleFactory ruleFactory;
private final ImmutableMap<String, BuiltinRuleFunction> ruleFunctions;
private final RuleClassProvider ruleClassProvider;
@@ -408,16 +238,7 @@
*/
private ImmutableMap<String, PackageArgument<?>> createPackageArguments() {
ImmutableList.Builder<PackageArgument<?>> arguments =
- ImmutableList.<PackageArgument<?>>builder()
- .add(new DefaultDeprecation())
- .add(new DefaultDistribs())
- .add(new DefaultApplicableLicenses())
- .add(new DefaultLicenses())
- .add(new DefaultTestOnly())
- .add(new DefaultVisibility())
- .add(new Features())
- .add(new DefaultCompatibleWith())
- .add(new DefaultRestrictedTo());
+ ImmutableList.<PackageArgument<?>>builder().addAll(DefaultPackageArguments.get());
for (EnvironmentExtension extension : environmentExtensions) {
arguments.addAll(extension.getPackageArguments());
@@ -430,19 +251,6 @@
return packageArguments.build();
}
- public static RuleVisibility getVisibility(Label ruleLabel, List<Label> original)
- throws EvalException {
- RuleVisibility result;
-
- result = ConstantRuleVisibility.tryParse(original);
- if (result != null) {
- return result;
- }
-
- result = PackageGroupsRuleVisibility.tryParse(ruleLabel, original);
- return result;
- }
-
/** Returns a function-value implementing "package" in the specified package context. */
// TODO(cparsons): Migrate this function to be defined with @SkylarkCallable.
// TODO(adonovan): don't call this function twice (once for BUILD files and
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageUtils.java b/src/main/java/com/google/devtools/build/lib/packages/PackageUtils.java
new file mode 100644
index 0000000..5d8e06d
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageUtils.java
@@ -0,0 +1,38 @@
+// Copyright 2020 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.packages;
+
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.syntax.EvalException;
+import java.util.List;
+
+/** Miscellaneous utils internal to Packages. */
+final class PackageUtils {
+
+ private PackageUtils() {}
+
+ static RuleVisibility getVisibility(Label ruleLabel, List<Label> original)
+ throws EvalException {
+ RuleVisibility result;
+
+ result = ConstantRuleVisibility.tryParse(original);
+ if (result != null) {
+ return result;
+ }
+
+ result = PackageGroupsRuleVisibility.tryParse(ruleLabel, original);
+ return result;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
index 4e78bea..0d9156c 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -2228,7 +2228,7 @@
eventHandler);
}
try {
- rule.setVisibility(PackageFactory.getVisibility(rule.getLabel(), attrList));
+ rule.setVisibility(PackageUtils.getVisibility(rule.getLabel(), attrList));
} catch (EvalException e) {
rule.reportError(rule.getLabel() + " " + e.getMessage(), eventHandler);
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeModule.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeModule.java
index f9ee14e..b6f9aae 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeModule.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeModule.java
@@ -200,7 +200,7 @@
RuleVisibility visibility =
EvalUtils.isNullOrNone(visibilityO)
? ConstantRuleVisibility.PUBLIC
- : PackageFactory.getVisibility(
+ : PackageUtils.getVisibility(
pkgBuilder.getBuildFileLabel(),
BuildType.LABEL_LIST.convert(
visibilityO, "'exports_files' operand", pkgBuilder.getBuildFileLabel()));