Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(984)

Side by Side Diff: tools/gn/scope_unittest.cc

Issue 2940873002: Implement tracking of BUILD.gn files used to define target, toolchain or (Closed)
Patch Set: Fix compilation after rebase. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/gn/scope_per_file_provider_unittest.cc ('k') | tools/gn/settings.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "testing/gtest/include/gtest/gtest.h" 5 #include "testing/gtest/include/gtest/gtest.h"
6 #include "tools/gn/input_file.h" 6 #include "tools/gn/input_file.h"
7 #include "tools/gn/parse_tree.h" 7 #include "tools/gn/parse_tree.h"
8 #include "tools/gn/scope.h" 8 #include "tools/gn/scope.h"
9 #include "tools/gn/template.h" 9 #include "tools/gn/template.h"
10 #include "tools/gn/test_with_scope.h" 10 #include "tools/gn/test_with_scope.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 // Add some templates to the scope. 44 // Add some templates to the scope.
45 FunctionCallNode templ_definition; 45 FunctionCallNode templ_definition;
46 scoped_refptr<Template> templ(new Template(setup.scope(), &templ_definition)); 46 scoped_refptr<Template> templ(new Template(setup.scope(), &templ_definition));
47 setup.scope()->AddTemplate("templ", templ.get()); 47 setup.scope()->AddTemplate("templ", templ.get());
48 scoped_refptr<Template> private_templ( 48 scoped_refptr<Template> private_templ(
49 new Template(setup.scope(), &templ_definition)); 49 new Template(setup.scope(), &templ_definition));
50 setup.scope()->AddTemplate("_templ", private_templ.get()); 50 setup.scope()->AddTemplate("_templ", private_templ.get());
51 51
52 // Detect collisions of values' values. 52 // Detect collisions of values' values.
53 { 53 {
54 Scope new_scope(setup.settings()); 54 Scope new_scope(setup.settings(), {});
55 Value new_value(&assignment, "goodbye"); 55 Value new_value(&assignment, "goodbye");
56 new_scope.SetValue("v", new_value, &assignment); 56 new_scope.SetValue("v", new_value, &assignment);
57 57
58 Err err; 58 Err err;
59 EXPECT_FALSE(setup.scope()->NonRecursiveMergeTo( 59 EXPECT_FALSE(setup.scope()->NonRecursiveMergeTo(
60 &new_scope, Scope::MergeOptions(), 60 &new_scope, Scope::MergeOptions(),
61 &assignment, "error", &err)); 61 &assignment, "error", &err));
62 EXPECT_TRUE(err.has_error()); 62 EXPECT_TRUE(err.has_error());
63 } 63 }
64 64
65 // Template name collisions. 65 // Template name collisions.
66 { 66 {
67 Scope new_scope(setup.settings()); 67 Scope new_scope(setup.settings(), {});
68 68
69 scoped_refptr<Template> new_templ( 69 scoped_refptr<Template> new_templ(
70 new Template(&new_scope, &templ_definition)); 70 new Template(&new_scope, &templ_definition));
71 new_scope.AddTemplate("templ", new_templ.get()); 71 new_scope.AddTemplate("templ", new_templ.get());
72 72
73 Err err; 73 Err err;
74 EXPECT_FALSE(setup.scope()->NonRecursiveMergeTo( 74 EXPECT_FALSE(setup.scope()->NonRecursiveMergeTo(
75 &new_scope, Scope::MergeOptions(), &assignment, "error", &err)); 75 &new_scope, Scope::MergeOptions(), &assignment, "error", &err));
76 EXPECT_TRUE(err.has_error()); 76 EXPECT_TRUE(err.has_error());
77 } 77 }
78 78
79 // The clobber flag should just overwrite colliding values. 79 // The clobber flag should just overwrite colliding values.
80 { 80 {
81 Scope new_scope(setup.settings()); 81 Scope new_scope(setup.settings(), {});
82 Value new_value(&assignment, "goodbye"); 82 Value new_value(&assignment, "goodbye");
83 new_scope.SetValue("v", new_value, &assignment); 83 new_scope.SetValue("v", new_value, &assignment);
84 84
85 Err err; 85 Err err;
86 Scope::MergeOptions options; 86 Scope::MergeOptions options;
87 options.clobber_existing = true; 87 options.clobber_existing = true;
88 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo( 88 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(
89 &new_scope, options, &assignment, "error", &err)); 89 &new_scope, options, &assignment, "error", &err));
90 EXPECT_FALSE(err.has_error()); 90 EXPECT_FALSE(err.has_error());
91 91
92 const Value* found_value = new_scope.GetValue("v"); 92 const Value* found_value = new_scope.GetValue("v");
93 ASSERT_TRUE(found_value); 93 ASSERT_TRUE(found_value);
94 EXPECT_TRUE(old_value == *found_value); 94 EXPECT_TRUE(old_value == *found_value);
95 } 95 }
96 96
97 // Clobber flag for templates. 97 // Clobber flag for templates.
98 { 98 {
99 Scope new_scope(setup.settings()); 99 Scope new_scope(setup.settings(), {});
100 100
101 scoped_refptr<Template> new_templ( 101 scoped_refptr<Template> new_templ(
102 new Template(&new_scope, &templ_definition)); 102 new Template(&new_scope, &templ_definition));
103 new_scope.AddTemplate("templ", new_templ.get()); 103 new_scope.AddTemplate("templ", new_templ.get());
104 Scope::MergeOptions options; 104 Scope::MergeOptions options;
105 options.clobber_existing = true; 105 options.clobber_existing = true;
106 106
107 Err err; 107 Err err;
108 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo( 108 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(
109 &new_scope, options, &assignment, "error", &err)); 109 &new_scope, options, &assignment, "error", &err));
110 EXPECT_FALSE(err.has_error()); 110 EXPECT_FALSE(err.has_error());
111 111
112 const Template* found_value = new_scope.GetTemplate("templ"); 112 const Template* found_value = new_scope.GetTemplate("templ");
113 ASSERT_TRUE(found_value); 113 ASSERT_TRUE(found_value);
114 EXPECT_TRUE(templ.get() == found_value); 114 EXPECT_TRUE(templ.get() == found_value);
115 } 115 }
116 116
117 // Don't flag values that technically collide but have the same value. 117 // Don't flag values that technically collide but have the same value.
118 { 118 {
119 Scope new_scope(setup.settings()); 119 Scope new_scope(setup.settings(), {});
120 Value new_value(&assignment, "hello"); 120 Value new_value(&assignment, "hello");
121 new_scope.SetValue("v", new_value, &assignment); 121 new_scope.SetValue("v", new_value, &assignment);
122 122
123 Err err; 123 Err err;
124 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo( 124 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(
125 &new_scope, Scope::MergeOptions(), &assignment, "error", &err)); 125 &new_scope, Scope::MergeOptions(), &assignment, "error", &err));
126 EXPECT_FALSE(err.has_error()); 126 EXPECT_FALSE(err.has_error());
127 } 127 }
128 128
129 // Templates that technically collide but are the same. 129 // Templates that technically collide but are the same.
130 { 130 {
131 Scope new_scope(setup.settings()); 131 Scope new_scope(setup.settings(), {});
132 132
133 scoped_refptr<Template> new_templ( 133 scoped_refptr<Template> new_templ(
134 new Template(&new_scope, &templ_definition)); 134 new Template(&new_scope, &templ_definition));
135 new_scope.AddTemplate("templ", templ.get()); 135 new_scope.AddTemplate("templ", templ.get());
136 136
137 Err err; 137 Err err;
138 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo( 138 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(
139 &new_scope, Scope::MergeOptions(), &assignment, "error", &err)); 139 &new_scope, Scope::MergeOptions(), &assignment, "error", &err));
140 EXPECT_FALSE(err.has_error()); 140 EXPECT_FALSE(err.has_error());
141 } 141 }
142 142
143 // Copy private values and templates. 143 // Copy private values and templates.
144 { 144 {
145 Scope new_scope(setup.settings()); 145 Scope new_scope(setup.settings(), {});
146 146
147 Err err; 147 Err err;
148 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo( 148 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(
149 &new_scope, Scope::MergeOptions(), &assignment, "error", &err)); 149 &new_scope, Scope::MergeOptions(), &assignment, "error", &err));
150 EXPECT_FALSE(err.has_error()); 150 EXPECT_FALSE(err.has_error());
151 EXPECT_TRUE(new_scope.GetValue(private_var_name)); 151 EXPECT_TRUE(new_scope.GetValue(private_var_name));
152 EXPECT_TRUE(new_scope.GetTemplate("_templ")); 152 EXPECT_TRUE(new_scope.GetTemplate("_templ"));
153 } 153 }
154 154
155 // Skip private values and templates. 155 // Skip private values and templates.
156 { 156 {
157 Scope new_scope(setup.settings()); 157 Scope new_scope(setup.settings(), {});
158 158
159 Err err; 159 Err err;
160 Scope::MergeOptions options; 160 Scope::MergeOptions options;
161 options.skip_private_vars = true; 161 options.skip_private_vars = true;
162 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo( 162 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(
163 &new_scope, options, &assignment, "error", &err)); 163 &new_scope, options, &assignment, "error", &err));
164 EXPECT_FALSE(err.has_error()); 164 EXPECT_FALSE(err.has_error());
165 EXPECT_FALSE(new_scope.GetValue(private_var_name)); 165 EXPECT_FALSE(new_scope.GetValue(private_var_name));
166 EXPECT_FALSE(new_scope.GetTemplate("_templ")); 166 EXPECT_FALSE(new_scope.GetTemplate("_templ"));
167 } 167 }
168 168
169 // Don't mark used. 169 // Don't mark used.
170 { 170 {
171 Scope new_scope(setup.settings()); 171 Scope new_scope(setup.settings(), {});
172 172
173 Err err; 173 Err err;
174 Scope::MergeOptions options; 174 Scope::MergeOptions options;
175 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo( 175 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(
176 &new_scope, options, &assignment, "error", &err)); 176 &new_scope, options, &assignment, "error", &err));
177 EXPECT_FALSE(err.has_error()); 177 EXPECT_FALSE(err.has_error());
178 EXPECT_FALSE(new_scope.CheckForUnusedVars(&err)); 178 EXPECT_FALSE(new_scope.CheckForUnusedVars(&err));
179 EXPECT_TRUE(err.has_error()); 179 EXPECT_TRUE(err.has_error());
180 } 180 }
181 181
182 // Mark dest used. 182 // Mark dest used.
183 { 183 {
184 Scope new_scope(setup.settings()); 184 Scope new_scope(setup.settings(), {});
185 185
186 Err err; 186 Err err;
187 Scope::MergeOptions options; 187 Scope::MergeOptions options;
188 options.mark_dest_used = true; 188 options.mark_dest_used = true;
189 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo( 189 EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(
190 &new_scope, options, &assignment, "error", &err)); 190 &new_scope, options, &assignment, "error", &err));
191 EXPECT_FALSE(err.has_error()); 191 EXPECT_FALSE(err.has_error());
192 EXPECT_TRUE(new_scope.CheckForUnusedVars(&err)); 192 EXPECT_TRUE(new_scope.CheckForUnusedVars(&err));
193 EXPECT_FALSE(err.has_error()); 193 EXPECT_FALSE(err.has_error());
194 } 194 }
195
196 // Input files are merged.
197 {
198 InputFile gni_input_file(SourceFile("//features.gni"));
199 InputFile root_input_file(SourceFile("//BUILD.gn"));
200 Scope gni_scope(setup.settings(), {&gni_input_file});
201 Scope new_scope(setup.settings(), {&root_input_file});
202
203 Err err;
204 Scope::MergeOptions options;
205 EXPECT_TRUE(gni_scope.NonRecursiveMergeTo(&new_scope, options, &assignment,
206 "error", &err));
207 EXPECT_FALSE(err.has_error());
208 const auto& input_files = new_scope.input_files();
209 EXPECT_NE(input_files.end(), input_files.find(&gni_input_file));
210 EXPECT_NE(input_files.end(), input_files.find(&root_input_file));
211 }
195 } 212 }
196 213
197 TEST(Scope, MakeClosure) { 214 TEST(Scope, MakeClosure) {
198 // Create 3 nested scopes [const root from setup] <- nested1 <- nested2. 215 // Create 3 nested scopes [const root from setup] <- nested1 <- nested2.
199 TestWithScope setup; 216 TestWithScope setup;
200 217
201 // Make a pretend parse node with proper tracking that we can blame for the 218 // Make a pretend parse node with proper tracking that we can blame for the
202 // given value. 219 // given value.
203 InputFile input_file(SourceFile("//foo")); 220 InputFile input_file(SourceFile("//foo"));
204 Token assignment_token(Location(&input_file, 1, 1, 1), Token::STRING, 221 Token assignment_token(Location(&input_file, 1, 1, 1), Token::STRING,
205 "\"hello\""); 222 "\"hello\"");
206 LiteralNode assignment; 223 LiteralNode assignment;
207 assignment.set_value(assignment_token); 224 assignment.set_value(assignment_token);
208 setup.scope()->SetValue("on_root", Value(&assignment, "on_root"), 225 setup.scope()->SetValue("on_root", Value(&assignment, "on_root"),
209 &assignment); 226 &assignment);
227 InputFile gni_input_file(SourceFile("//features.gni"));
228 setup.scope()->AddInputFile(&gni_input_file);
210 229
211 // Root scope should be const from the nested caller's perspective. 230 // Root scope should be const from the nested caller's perspective.
212 Scope nested1(static_cast<const Scope*>(setup.scope())); 231 Scope nested1(static_cast<const Scope*>(setup.scope()));
213 nested1.SetValue("on_one", Value(&assignment, "on_one"), &assignment); 232 nested1.SetValue("on_one", Value(&assignment, "on_one"), &assignment);
214 233
215 Scope nested2(&nested1); 234 Scope nested2(&nested1);
216 nested2.SetValue("on_one", Value(&assignment, "on_two"), &assignment); 235 nested2.SetValue("on_one", Value(&assignment, "on_two"), &assignment);
217 nested2.SetValue("on_two", Value(&assignment, "on_two2"), &assignment); 236 nested2.SetValue("on_two", Value(&assignment, "on_two2"), &assignment);
218 237
219 // Making a closure from the root scope. 238 // Making a closure from the root scope.
220 std::unique_ptr<Scope> result = setup.scope()->MakeClosure(); 239 std::unique_ptr<Scope> result = setup.scope()->MakeClosure();
221 EXPECT_FALSE(result->containing()); // Should have no containing scope. 240 EXPECT_FALSE(result->containing()); // Should have no containing scope.
222 EXPECT_TRUE(result->GetValue("on_root")); // Value should be copied. 241 EXPECT_TRUE(result->GetValue("on_root")); // Value should be copied.
223 242
224 // Making a closure from the second nested scope. 243 // Making a closure from the second nested scope.
225 result = nested2.MakeClosure(); 244 result = nested2.MakeClosure();
226 EXPECT_EQ(setup.scope(), 245 EXPECT_EQ(setup.scope(),
227 result->containing()); // Containing scope should be the root. 246 result->containing()); // Containing scope should be the root.
228 EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_root", "on_root")); 247 EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_root", "on_root"));
229 EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_one", "on_two")); 248 EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_one", "on_two"));
230 EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_two", "on_two2")); 249 EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_two", "on_two2"));
250
251 {
252 const auto& input_files = nested1.input_files();
253 EXPECT_NE(input_files.end(), input_files.find(&gni_input_file));
254 }
255 {
256 const auto& input_files = nested2.input_files();
257 EXPECT_NE(input_files.end(), input_files.find(&gni_input_file));
258 }
231 } 259 }
232 260
233 TEST(Scope, GetMutableValue) { 261 TEST(Scope, GetMutableValue) {
234 TestWithScope setup; 262 TestWithScope setup;
235 263
236 // Make a pretend parse node with proper tracking that we can blame for the 264 // Make a pretend parse node with proper tracking that we can blame for the
237 // given value. 265 // given value.
238 InputFile input_file(SourceFile("//foo")); 266 InputFile input_file(SourceFile("//foo"));
239 Token assignment_token(Location(&input_file, 1, 1, 1), Token::STRING, 267 Token assignment_token(Location(&input_file, 1, 1, 1), Token::STRING,
240 "\"hello\""); 268 "\"hello\"");
241 LiteralNode assignment; 269 LiteralNode assignment;
242 assignment.set_value(assignment_token); 270 assignment.set_value(assignment_token);
243 271
244 const char kOnConst[] = "on_const"; 272 const char kOnConst[] = "on_const";
245 const char kOnMutable1[] = "on_mutable1"; 273 const char kOnMutable1[] = "on_mutable1";
246 const char kOnMutable2[] = "on_mutable2"; 274 const char kOnMutable2[] = "on_mutable2";
247 275
248 Value value(&assignment, "hello"); 276 Value value(&assignment, "hello");
249 277
250 // Create a root scope with one value. 278 // Create a root scope with one value.
251 Scope root_scope(setup.settings()); 279 Scope root_scope(setup.settings(), {});
252 root_scope.SetValue(kOnConst, value, &assignment); 280 root_scope.SetValue(kOnConst, value, &assignment);
253 281
254 // Create a first nested scope with a different value. 282 // Create a first nested scope with a different value.
255 const Scope* const_root_scope = &root_scope; 283 const Scope* const_root_scope = &root_scope;
256 Scope mutable_scope1(const_root_scope); 284 Scope mutable_scope1(const_root_scope);
257 mutable_scope1.SetValue(kOnMutable1, value, &assignment); 285 mutable_scope1.SetValue(kOnMutable1, value, &assignment);
258 286
259 // Create a second nested scope with a different value. 287 // Create a second nested scope with a different value.
260 Scope mutable_scope2(&mutable_scope1); 288 Scope mutable_scope2(&mutable_scope1);
261 mutable_scope2.SetValue(kOnMutable2, value, &assignment); 289 mutable_scope2.SetValue(kOnMutable2, value, &assignment);
(...skipping 28 matching lines...) Expand all
290 318
291 TEST(Scope, RemovePrivateIdentifiers) { 319 TEST(Scope, RemovePrivateIdentifiers) {
292 TestWithScope setup; 320 TestWithScope setup;
293 setup.scope()->SetValue("a", Value(nullptr, true), nullptr); 321 setup.scope()->SetValue("a", Value(nullptr, true), nullptr);
294 setup.scope()->SetValue("_b", Value(nullptr, true), nullptr); 322 setup.scope()->SetValue("_b", Value(nullptr, true), nullptr);
295 323
296 setup.scope()->RemovePrivateIdentifiers(); 324 setup.scope()->RemovePrivateIdentifiers();
297 EXPECT_TRUE(setup.scope()->GetValue("a")); 325 EXPECT_TRUE(setup.scope()->GetValue("a"));
298 EXPECT_FALSE(setup.scope()->GetValue("_b")); 326 EXPECT_FALSE(setup.scope()->GetValue("_b"));
299 } 327 }
OLDNEW
« no previous file with comments | « tools/gn/scope_per_file_provider_unittest.cc ('k') | tools/gn/settings.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698