| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "tools/gn/err.h" | 5 #include "tools/gn/err.h" |
| 6 #include "tools/gn/functions.h" | 6 #include "tools/gn/functions.h" |
| 7 #include "tools/gn/parse_node_value_adapter.h" |
| 7 #include "tools/gn/parse_tree.h" | 8 #include "tools/gn/parse_tree.h" |
| 8 #include "tools/gn/scope.h" | 9 #include "tools/gn/scope.h" |
| 9 | 10 |
| 10 namespace functions { | 11 namespace functions { |
| 11 | 12 |
| 12 const char kForEach[] = "foreach"; | 13 const char kForEach[] = "foreach"; |
| 13 const char kForEach_HelpShort[] = | 14 const char kForEach_HelpShort[] = |
| 14 "foreach: Iterate over a list."; | 15 "foreach: Iterate over a list."; |
| 15 const char kForEach_Help[] = | 16 const char kForEach_Help[] = |
| 16 "foreach: Iterate over a list.\n" | 17 "foreach: Iterate over a list.\n" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 | 57 |
| 57 // Extract the loop variable. | 58 // Extract the loop variable. |
| 58 const IdentifierNode* identifier = args_vector[0]->AsIdentifier(); | 59 const IdentifierNode* identifier = args_vector[0]->AsIdentifier(); |
| 59 if (!identifier) { | 60 if (!identifier) { |
| 60 *err = | 61 *err = |
| 61 Err(args_vector[0].get(), "Expected an identifier for the loop var."); | 62 Err(args_vector[0].get(), "Expected an identifier for the loop var."); |
| 62 return Value(); | 63 return Value(); |
| 63 } | 64 } |
| 64 base::StringPiece loop_var(identifier->value().value()); | 65 base::StringPiece loop_var(identifier->value().value()); |
| 65 | 66 |
| 66 // Extract the list, avoid a copy if it's an identifier (common case). | 67 // Extract the list to iterate over. |
| 67 Value value_storage_for_exec; // Backing for list_value when we need to exec. | 68 ParseNodeValueAdapter list_adapter; |
| 68 const Value* list_value = nullptr; | 69 if (!list_adapter.InitForType(scope, args_vector[1].get(), Value::LIST, err)) |
| 69 const IdentifierNode* list_identifier = args_vector[1]->AsIdentifier(); | |
| 70 if (list_identifier) { | |
| 71 list_value = scope->GetValue(list_identifier->value().value(), true); | |
| 72 if (!list_value) { | |
| 73 *err = Err(args_vector[1].get(), "Undefined identifier."); | |
| 74 return Value(); | |
| 75 } | |
| 76 } else { | |
| 77 // Not an identifier, evaluate the node to get the result. | |
| 78 Scope list_exec_scope(scope); | |
| 79 value_storage_for_exec = args_vector[1]->Execute(scope, err); | |
| 80 if (err->has_error()) | |
| 81 return Value(); | |
| 82 list_value = &value_storage_for_exec; | |
| 83 } | |
| 84 if (!list_value->VerifyTypeIs(Value::LIST, err)) | |
| 85 return Value(); | 70 return Value(); |
| 86 const std::vector<Value>& list = list_value->list_value(); | 71 const std::vector<Value>& list = list_adapter.get().list_value(); |
| 87 | 72 |
| 88 // Block to execute. | 73 // Block to execute. |
| 89 const BlockNode* block = function->block(); | 74 const BlockNode* block = function->block(); |
| 90 if (!block) { | 75 if (!block) { |
| 91 *err = Err(function, "Expected { after foreach."); | 76 *err = Err(function, "Expected { after foreach."); |
| 92 return Value(); | 77 return Value(); |
| 93 } | 78 } |
| 94 | 79 |
| 95 // If the loop variable was previously defined in this scope, save it so we | 80 // If the loop variable was previously defined in this scope, save it so we |
| 96 // can put it back after the loop is done. | 81 // can put it back after the loop is done. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 113 scope->SetValue(loop_var, old_loop_value, old_loop_value.origin()); | 98 scope->SetValue(loop_var, old_loop_value, old_loop_value.origin()); |
| 114 } else { | 99 } else { |
| 115 // Loop variable was undefined before loop, delete it. | 100 // Loop variable was undefined before loop, delete it. |
| 116 scope->RemoveIdentifier(loop_var); | 101 scope->RemoveIdentifier(loop_var); |
| 117 } | 102 } |
| 118 | 103 |
| 119 return Value(); | 104 return Value(); |
| 120 } | 105 } |
| 121 | 106 |
| 122 } // namespace functions | 107 } // namespace functions |
| OLD | NEW |