| Index: tools/gn/functions.cc
|
| diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc
|
| index 1d17d42988d9bfe4f8989e34cdb1bfb4d2787a91..23319e4b59a9cd50a4da595a853031babb1e3c14 100644
|
| --- a/tools/gn/functions.cc
|
| +++ b/tools/gn/functions.cc
|
| @@ -638,6 +638,122 @@ Value RunImport(Scope* scope,
|
| return Value();
|
| }
|
|
|
| +// not_needed -----------------------------------------------------------------
|
| +
|
| +const char kNotNeeded[] = "not_needed";
|
| +const char kNotNeeded_HelpShort[] =
|
| + "not_needed: Mark variables from scope as not needed.";
|
| +const char kNotNeeded_Help[] =
|
| + R"(not_needed: Mark variables from scope as not needed.
|
| +
|
| + not_needed(variable_list_or_star, variable_to_ignore_list = [])
|
| + not_needed(from_scope, variable_list_or_star,
|
| + variable_to_ignore_list = [])
|
| +
|
| + Mark the variables in the current or given scope as not needed, which means
|
| + you will not get an error about unused variables for these. The
|
| + variable_to_ignore_list allows excluding variables from "all matches" if
|
| + variable_list_or_star is "*".
|
| +
|
| +Example
|
| +
|
| + not_needed("*", [ "config" ])
|
| + not_needed([ "data_deps", "deps" ])
|
| + not_needed(invoker, "*", [ "config" ])
|
| + not_needed(invoker, [ "data_deps", "deps" ])
|
| +)";
|
| +
|
| +Value RunNotNeeded(Scope* scope,
|
| + const FunctionCallNode* function,
|
| + const ListNode* args_list,
|
| + Err* err) {
|
| + const auto& args_vector = args_list->contents();
|
| + if (args_vector.size() < 1 && args_vector.size() > 3) {
|
| + *err = Err(function, "Wrong number of arguments.",
|
| + "Expecting one, two or three arguments.");
|
| + return Value();
|
| + }
|
| + auto args_cur = args_vector.begin();
|
| +
|
| + Value* value = nullptr; // Value to use, may point to result_value.
|
| + Value result_value; // Storage for the "evaluate" case.
|
| + const IdentifierNode* identifier = (*args_cur)->AsIdentifier();
|
| + if (identifier) {
|
| + // Optimize the common case where the input scope is an identifier. This
|
| + // prevents a copy of a potentially large Scope object.
|
| + value = scope->GetMutableValue(identifier->value().value(),
|
| + Scope::SEARCH_NESTED, true);
|
| + if (!value) {
|
| + *err = Err(identifier, "Undefined identifier.");
|
| + return Value();
|
| + }
|
| + } else {
|
| + // Non-optimized case, just evaluate the argument.
|
| + result_value = (*args_cur)->Execute(scope, err);
|
| + if (err->has_error())
|
| + return Value();
|
| + value = &result_value;
|
| + }
|
| + args_cur++;
|
| +
|
| + // Extract the source scope if different from current one.
|
| + Scope* source = scope;
|
| + if (value->type() == Value::SCOPE) {
|
| + source = value->scope_value();
|
| + result_value = (*args_cur)->Execute(scope, err);
|
| + if (err->has_error())
|
| + return Value();
|
| + value = &result_value;
|
| + args_cur++;
|
| + }
|
| +
|
| + // Extract the exclusion list if defined.
|
| + Value exclusion_value;
|
| + std::set<std::string> exclusion_set;
|
| + if (args_cur != args_vector.end()) {
|
| + exclusion_value = (*args_cur)->Execute(source, err);
|
| + if (err->has_error())
|
| + return Value();
|
| +
|
| + if (exclusion_value.type() != Value::LIST) {
|
| + *err = Err(exclusion_value, "Not a valid list of variables to exclude.",
|
| + "Expecting a list of strings.");
|
| + return Value();
|
| + }
|
| +
|
| + for (const Value& cur : exclusion_value.list_value()) {
|
| + if (!cur.VerifyTypeIs(Value::STRING, err))
|
| + return Value();
|
| +
|
| + exclusion_set.insert(cur.string_value());
|
| + }
|
| + }
|
| +
|
| + if (value->type() == Value::STRING) {
|
| + if (value->string_value() == "*") {
|
| + source->MarkAllUsed(exclusion_set);
|
| + return Value();
|
| + }
|
| + } else if (value->type() == Value::LIST) {
|
| + if (exclusion_value.type() != Value::NONE) {
|
| + *err = Err(exclusion_value, "Not supported with a variable list.",
|
| + "Exclusion list can only be used with the string \"*\".");
|
| + return Value();
|
| + }
|
| + for (const Value& cur : value->list_value()) {
|
| + if (!cur.VerifyTypeIs(Value::STRING, err))
|
| + return Value();
|
| + source->MarkUsed(cur.string_value());
|
| + }
|
| + return Value();
|
| + }
|
| +
|
| + // Not the right type of argument.
|
| + *err = Err(*value, "Not a valid list of variables.",
|
| + "Expecting either the string \"*\" or a list of strings.");
|
| + return Value();
|
| +}
|
| +
|
| // set_sources_assignment_filter -----------------------------------------------
|
|
|
| const char kSetSourcesAssignmentFilter[] = "set_sources_assignment_filter";
|
| @@ -1040,6 +1156,7 @@ struct FunctionInfoInitializer {
|
| INSERT_FUNCTION(GetPathInfo, false)
|
| INSERT_FUNCTION(GetTargetOutputs, false)
|
| INSERT_FUNCTION(Import, false)
|
| + INSERT_FUNCTION(NotNeeded, false)
|
| INSERT_FUNCTION(Pool, false)
|
| INSERT_FUNCTION(Print, false)
|
| INSERT_FUNCTION(ProcessFileTemplate, false)
|
|
|