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

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: Created 3 years, 6 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
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 // Source file hashes are merged.
197 {
198 Scope gni_scope(setup.settings(), {base::Hash("//features.gni")});
199 Scope new_scope(setup.settings(), {base::Hash("//BUILD.gn")});
200
201 Err err;
202 Scope::MergeOptions options;
203 EXPECT_TRUE(gni_scope.NonRecursiveMergeTo(&new_scope, options, &assignment,
204 "error", &err));
205 EXPECT_FALSE(err.has_error());
206 const auto& source_files_hashes = new_scope.source_files_hashes();
207 EXPECT_NE(source_files_hashes.end(),
208 source_files_hashes.find(base::Hash("//features.gni")));
209 EXPECT_NE(source_files_hashes.end(),
210 source_files_hashes.find(base::Hash("//BUILD.gn")));
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 setup.scope()->AddSourceFile(SourceFile("//features.gni"));
210 228
211 // Root scope should be const from the nested caller's perspective. 229 // Root scope should be const from the nested caller's perspective.
212 Scope nested1(static_cast<const Scope*>(setup.scope())); 230 Scope nested1(static_cast<const Scope*>(setup.scope()));
213 nested1.SetValue("on_one", Value(&assignment, "on_one"), &assignment); 231 nested1.SetValue("on_one", Value(&assignment, "on_one"), &assignment);
214 232
215 Scope nested2(&nested1); 233 Scope nested2(&nested1);
216 nested2.SetValue("on_one", Value(&assignment, "on_two"), &assignment); 234 nested2.SetValue("on_one", Value(&assignment, "on_two"), &assignment);
217 nested2.SetValue("on_two", Value(&assignment, "on_two2"), &assignment); 235 nested2.SetValue("on_two", Value(&assignment, "on_two2"), &assignment);
218 236
219 // Making a closure from the root scope. 237 // Making a closure from the root scope.
220 std::unique_ptr<Scope> result = setup.scope()->MakeClosure(); 238 std::unique_ptr<Scope> result = setup.scope()->MakeClosure();
221 EXPECT_FALSE(result->containing()); // Should have no containing scope. 239 EXPECT_FALSE(result->containing()); // Should have no containing scope.
222 EXPECT_TRUE(result->GetValue("on_root")); // Value should be copied. 240 EXPECT_TRUE(result->GetValue("on_root")); // Value should be copied.
223 241
224 // Making a closure from the second nested scope. 242 // Making a closure from the second nested scope.
225 result = nested2.MakeClosure(); 243 result = nested2.MakeClosure();
226 EXPECT_EQ(setup.scope(), 244 EXPECT_EQ(setup.scope(),
227 result->containing()); // Containing scope should be the root. 245 result->containing()); // Containing scope should be the root.
228 EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_root", "on_root")); 246 EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_root", "on_root"));
229 EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_one", "on_two")); 247 EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_one", "on_two"));
230 EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_two", "on_two2")); 248 EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_two", "on_two2"));
249
250 {
251 const auto& source_files_hashes = nested1.source_files_hashes();
252 EXPECT_NE(source_files_hashes.end(),
253 source_files_hashes.find(base::Hash("//features.gni")));
254 }
255 {
256 const auto& source_files_hashes = nested2.source_files_hashes();
257 EXPECT_NE(source_files_hashes.end(),
258 source_files_hashes.find(base::Hash("//features.gni")));
259 }
231 } 260 }
232 261
233 TEST(Scope, GetMutableValue) { 262 TEST(Scope, GetMutableValue) {
234 TestWithScope setup; 263 TestWithScope setup;
235 264
236 // Make a pretend parse node with proper tracking that we can blame for the 265 // Make a pretend parse node with proper tracking that we can blame for the
237 // given value. 266 // given value.
238 InputFile input_file(SourceFile("//foo")); 267 InputFile input_file(SourceFile("//foo"));
239 Token assignment_token(Location(&input_file, 1, 1, 1), Token::STRING, 268 Token assignment_token(Location(&input_file, 1, 1, 1), Token::STRING,
240 "\"hello\""); 269 "\"hello\"");
241 LiteralNode assignment; 270 LiteralNode assignment;
242 assignment.set_value(assignment_token); 271 assignment.set_value(assignment_token);
243 272
244 const char kOnConst[] = "on_const"; 273 const char kOnConst[] = "on_const";
245 const char kOnMutable1[] = "on_mutable1"; 274 const char kOnMutable1[] = "on_mutable1";
246 const char kOnMutable2[] = "on_mutable2"; 275 const char kOnMutable2[] = "on_mutable2";
247 276
248 Value value(&assignment, "hello"); 277 Value value(&assignment, "hello");
249 278
250 // Create a root scope with one value. 279 // Create a root scope with one value.
251 Scope root_scope(setup.settings()); 280 Scope root_scope(setup.settings(), {});
252 root_scope.SetValue(kOnConst, value, &assignment); 281 root_scope.SetValue(kOnConst, value, &assignment);
253 282
254 // Create a first nested scope with a different value. 283 // Create a first nested scope with a different value.
255 const Scope* const_root_scope = &root_scope; 284 const Scope* const_root_scope = &root_scope;
256 Scope mutable_scope1(const_root_scope); 285 Scope mutable_scope1(const_root_scope);
257 mutable_scope1.SetValue(kOnMutable1, value, &assignment); 286 mutable_scope1.SetValue(kOnMutable1, value, &assignment);
258 287
259 // Create a second nested scope with a different value. 288 // Create a second nested scope with a different value.
260 Scope mutable_scope2(&mutable_scope1); 289 Scope mutable_scope2(&mutable_scope1);
261 mutable_scope2.SetValue(kOnMutable2, value, &assignment); 290 mutable_scope2.SetValue(kOnMutable2, value, &assignment);
(...skipping 28 matching lines...) Expand all
290 319
291 TEST(Scope, RemovePrivateIdentifiers) { 320 TEST(Scope, RemovePrivateIdentifiers) {
292 TestWithScope setup; 321 TestWithScope setup;
293 setup.scope()->SetValue("a", Value(nullptr, true), nullptr); 322 setup.scope()->SetValue("a", Value(nullptr, true), nullptr);
294 setup.scope()->SetValue("_b", Value(nullptr, true), nullptr); 323 setup.scope()->SetValue("_b", Value(nullptr, true), nullptr);
295 324
296 setup.scope()->RemovePrivateIdentifiers(); 325 setup.scope()->RemovePrivateIdentifiers();
297 EXPECT_TRUE(setup.scope()->GetValue("a")); 326 EXPECT_TRUE(setup.scope()->GetValue("a"));
298 EXPECT_FALSE(setup.scope()->GetValue("_b")); 327 EXPECT_FALSE(setup.scope()->GetValue("_b"));
299 } 328 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698