Chromium Code Reviews| Index: tools/gn/functions.cc |
| diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc |
| index 272cd9430bc96d82fef310a8f8ef5600cd3e2725..9299d4d1f4b9e230134bae5b4bac7b07595d4079 100644 |
| --- a/tools/gn/functions.cc |
| +++ b/tools/gn/functions.cc |
| @@ -134,7 +134,7 @@ bool FillTargetBlockScope(const Scope* scope, |
| const base::StringPiece target_name(variables::kTargetName); |
| block_scope->SetValue(target_name, Value(function, args[0].string_value()), |
| function); |
| - block_scope->MarkUsed(target_name); |
| + block_scope->MarkUsed(target_name, err); |
| return true; |
| } |
| @@ -638,6 +638,110 @@ Value RunImport(Scope* scope, |
| return Value(); |
| } |
| +// not_needed ----------------------------------------------------------------- |
| + |
| +const char kNotNeeded[] = "not_needed"; |
| +const char kNotNeeded_HelpShort[] = |
| + "not_needed: Mark variables from scope as unusedd."; |
|
brettw
2017/06/20 17:27:25
"unusedd" spelling
Petr Hosek
2017/06/21 02:17:40
Done.
|
| +const char kNotNeeded_Help[] = |
| + R"(not_needed: Mark variables from scope as unused. |
| + |
| + not_needed(from_scope, variable_list_or_star, |
| + variable_to_ignore_list = []) |
| + |
| + Mark the variables from the given scope as not being used in the current |
| + scope. Any past or future uses of these variables within the current scope |
| + will fail with an error. |
| + |
| +Example |
| + |
| + not_needed(invoker, "*", [ "config" ]) |
| + not_needed(invoker, [ "data_deps", "deps" ]) |
|
brettw
2017/06/20 17:27:25
Can you add support for a third form that modifies
Petr Hosek
2017/06/21 02:17:40
Done.
|
| +)"; |
| + |
| +Value RunNotNeeded(Scope* scope, |
| + const FunctionCallNode* function, |
| + const ListNode* args_list, |
| + Err* err) { |
| + const auto& args_vector = args_list->contents(); |
| + if (args_vector.size() != 2 && args_vector.size() != 3) { |
| + *err = Err(function, "Wrong number of arguments.", |
| + "Expecting two or three arguments."); |
| + return Value(); |
| + } |
| + |
| + Value* value = nullptr; // Value to use, may point to result_value. |
| + Value result_value; // Storage for the "evaluate" case. |
| + const IdentifierNode* identifier = args_vector[0]->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_vector[0]->Execute(scope, err); |
| + if (err->has_error()) |
| + return Value(); |
| + value = &result_value; |
| + } |
| + |
| + // Extract the source scope. |
| + if (!value->VerifyTypeIs(Value::SCOPE, err)) |
| + return Value(); |
| + Scope* source = value->scope_value(); |
| + |
| + // Extract the exclusion list if defined. |
| + std::set<std::string> exclusion_set; |
| + if (args_vector.size() == 3) { |
| + Value exclusion_value = args_vector[2]->Execute(scope, 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()); |
| + } |
| + } |
| + |
| + // Extract the list. If all_values is not set, the what_value will be a list. |
| + Value what_value = args_vector[1]->Execute(scope, err); |
| + if (err->has_error()) |
| + return Value(); |
| + if (what_value.type() == Value::STRING) { |
| + if (what_value.string_value() == "*") { |
| + source->MarkAllUnusable(err, exclusion_set); |
| + return Value(); |
| + } |
| + } else { |
| + if (what_value.type() == Value::LIST) { |
| + for (const Value& cur : what_value.list_value()) { |
| + if (!cur.VerifyTypeIs(Value::STRING, err)) |
| + return Value(); |
| + source->MarkUnusable(cur.string_value(), err); |
| + } |
| + return Value(); |
| + } |
| + } |
| + |
| + // Not the right type of argument. |
| + *err = Err(what_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 +1144,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) |