aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build
diff options
context:
space:
mode:
authorGravatar Florian Weikert <fwe@google.com>2015-08-25 13:16:16 +0000
committerGravatar Lukacs Berki <lberki@google.com>2015-08-26 07:37:13 +0000
commitab60010da4451721e98a7abd26e9bacea32cd173 (patch)
treebf9f5d281d4927904428b594a5cc6aa90b305a1d /src/main/java/com/google/devtools/build
parent15ab6ad6fbd09352ced025397891de2ea6d5bb7d (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/com/google/devtools/build')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java27
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java25
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();
+ }
}