diff options
author | 2015-08-25 13:16:16 +0000 | |
---|---|---|
committer | 2015-08-26 07:37:13 +0000 | |
commit | ab60010da4451721e98a7abd26e9bacea32cd173 (patch) | |
tree | bf9f5d281d4927904428b594a5cc6aa90b305a1d /src/main/java | |
parent | 15ab6ad6fbd09352ced025397891de2ea6d5bb7d (diff) |
Rules created by Skylark macros now have values for the attributes generator_name and generator_function.
Additionally, both Skylark macros and build extensions set the attribute generator_location in order to store the name of the file where generator_function was defined.
--
MOS_MIGRATED_REVID=101458757
Diffstat (limited to 'src/main/java')
3 files changed, 51 insertions, 2 deletions
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 48887ddf1b..bb615d8b92 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 @@ -205,6 +205,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/rules/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java index 6cdb75fb5c..b1c48d4dd3 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java +++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java @@ -321,14 +321,37 @@ public class SkylarkRuleClassFunctions { } RuleClass ruleClass = builder.build(ruleClassName); PackageContext pkgContext = (PackageContext) env.lookup(PackageFactory.PKG_CONTEXT); - return RuleFactory.createAndAddRule( - pkgContext, ruleClass, (Map<String, Object>) args[0], ast); + return RuleFactory.createAndAddRule(pkgContext, ruleClass, + addGeneratorAttributesForMacros((Map<String, Object>) args[0], env), ast); } catch (InvalidRuleException | NameConflictException | NoSuchVariableException e) { throw new EvalException(ast.getLocation(), e.getMessage()); } } /** + * If the current rule was created by a macro, this method sets the appropriate values for the + * attributes generator_{name, function, location} and returns a map of all attribute values. + * + * <p>Otherwise, the specified map of arguments is returned without any changes. + */ + private Map<String, Object> addGeneratorAttributesForMacros( + Map<String, Object> args, Environment env) { + ImmutableList<BaseFunction> stackTrace = env.getStackTrace(); + if (stackTrace.isEmpty()) { + // If there was a macro, it would be on the stack. + return args; + } + + BaseFunction generator = stackTrace.get(0); // BaseFunction + ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder(); + builder.putAll(args); + builder.put("generator_name", args.get("name")); + builder.put("generator_function", generator.getName()); + builder.put("generator_location", generator.getLocationPathAndLine()); + return builder.build(); + } + + /** * Export a RuleFunction from a Skylark file with a given name. */ void export(PathFragment skylarkFile, String ruleClassName) { diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java index 816110097b..7574e1fe4e 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java @@ -21,7 +21,9 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Ordering; import com.google.common.collect.Sets; import com.google.devtools.build.lib.events.Location; +import com.google.devtools.build.lib.events.Location.LineAndColumn; import com.google.devtools.build.lib.packages.Type.ConversionException; +import com.google.devtools.build.lib.vfs.PathFragment; import java.util.ArrayList; import java.util.HashMap; @@ -569,4 +571,27 @@ public abstract class BaseFunction { public int hashCode() { return Objects.hash(name, location); } + + /** + * Returns the location (filename:line) of the BaseFunction's definition. + * + * <p>If such a location is not defined, this method returns an empty string. + */ + public String getLocationPathAndLine() { + if (location == null) { + return ""; + } + + StringBuilder builder = new StringBuilder(); + PathFragment path = location.getPath(); + if (path != null) { + builder.append(path.getPathString()); + } + + LineAndColumn position = location.getStartLineAndColumn(); + if (position != null) { + builder.append(":").append(position.getLine()); + } + return builder.toString(); + } } |