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 |