From a75b7b7cdd28cb6709131f36e951a904a7ebb734 Mon Sep 17 00:00:00 2001 From: Florian Weikert Date: Tue, 6 Oct 2015 14:06:28 +0000 Subject: Rules created by Skylark Macros now store the workspace-relative path of the respective macro in the attribute "generator_location". -- MOS_MIGRATED_REVID=104757928 --- .../build/lib/analysis/BaseRuleClasses.java | 1 + .../devtools/build/lib/packages/RuleFactory.java | 27 +++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java index a7b7ae6ee8..6a1fa38b43 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java @@ -207,6 +207,7 @@ public class BaseRuleClasses { .nonconfigurable("low-level attribute, used in TargetUtils without configurations")) .add(attr("generator_name", STRING).undocumented("internal")) .add(attr("generator_function", STRING).undocumented("internal")) + .add(attr("generator_location", STRING).undocumented("internal")) .add(attr("testonly", BOOLEAN).value(testonlyDefault) .nonconfigurable("policy decision: rules testability should be consistent")) .add(attr("features", STRING_LIST).orderIndependent()) diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java b/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java index eba884e4c4..b3f4037442 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java @@ -111,7 +111,8 @@ public class RuleFactory { ruleClass + " cannot be in the WORKSPACE file " + "(used by " + label + ")"); } - AttributesAndLocation generator = generatorAttributesForMacros(attributeValues, env, location); + AttributesAndLocation generator = + generatorAttributesForMacros(attributeValues, env, location, label); try { return ruleClass.createRuleWithLabel( pkgBuilder, label, generator.attributes, eventHandler, ast, generator.location); @@ -197,7 +198,7 @@ public class RuleFactory { *

Otherwise, it returns the given attributes without any changes. */ private static AttributesAndLocation generatorAttributesForMacros( - Map args, @Nullable Environment env, Location location) { + Map args, @Nullable Environment env, Location location, Label label) { // Returns the original arguments if a) there is only the rule itself on the stack // trace (=> no macro) or b) the attributes have already been set by Python pre-processing. if (env == null) { @@ -218,18 +219,38 @@ public class RuleFactory { BaseFunction function = topCall.second; String name = generator.getNameArg(); ImmutableMap.Builder builder = ImmutableMap.builder(); + builder.putAll(args); builder.put("generator_name", (name == null) ? args.get("name") : name); builder.put("generator_function", function.getName()); + if (generator.getLocation() != null) { location = generator.getLocation(); + builder.put("generator_location", getRelativeLocation(location, label)); } try { return new AttributesAndLocation(builder.build(), location); } catch (IllegalArgumentException ex) { - // Just to play it safe. + // We just fall back to the default case and swallow any messages. return new AttributesAndLocation(args, location); } } + + /** + * Uses the given label to retrieve the workspace-relative path of the given location. + */ + private static String getRelativeLocation(Location location, Label label) { + String absolutePath = Location.printPathAndLine(location); + // Instead of using this substring-based approach, we would prefer to construct the path from + // the label itself, e.g. + // buildFileLabel.getPackageFragment().getRelative(buildFileLabel.getName()).getPathString(). + // However, this seems to conflict with python pre-processing since we had seen cases where the + // label of the BUILD file is something like //package:BUILD while the location is actually + // /path/to/workspace/package/with/subpackage/BUILD. Consequently, we would lose the + // "with/subpackage" part. + int pos = absolutePath.indexOf(label.getPackageName()); + Preconditions.checkArgument(pos > -1, "Cannot retrieve relative path for %s", absolutePath); + return absolutePath.substring(pos); + } } -- cgit v1.2.3