/** * If the rule was created by a macro, this method sets the appropriate values for the attributes * generator_{name, function, location} and returns all attributes. * * <p>Otherwise, it returns the given attributes without any changes. */ private static AttributesAndLocation generatorAttributesForMacros( BuildLangTypedAttributeValuesMap 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) { return new AttributesAndLocation(args, location); } boolean hasName = args.containsAttributeNamed("generator_name"); boolean hasFunc = args.containsAttributeNamed("generator_function"); // TODO(bazel-team): resolve cases in our code where hasName && !hasFunc, or hasFunc && !hasName if (hasName || hasFunc) { return new AttributesAndLocation(args, location); } Pair<FuncallExpression, BaseFunction> topCall = env.getTopCall(); if (topCall == null || !(topCall.second instanceof UserDefinedFunction)) { return new AttributesAndLocation(args, location); } FuncallExpression generator = topCall.first; BaseFunction function = topCall.second; String name = generator.getNameArg(); ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder(); for (String attributeName : args.getAttributeNames()) { builder.put(attributeName, args.getAttributeValue(attributeName)); } builder.put("generator_name", (name == null) ? args.getAttributeValue("name") : name); builder.put("generator_function", function.getName()); if (generator.getLocation() != null) { location = generator.getLocation(); } String relativePath = maybeGetRelativeLocation(location, label); if (relativePath != null) { builder.put("generator_location", relativePath); } try { return new AttributesAndLocation( new BuildLangTypedAttributeValuesMap(builder.build()), location); } catch (IllegalArgumentException ex) { // We just fall back to the default case and swallow any messages. return new AttributesAndLocation(args, location); } }