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

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

Issue 318383003: Improve error messages and reporting in GN (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 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 | Annotate | Revision Log
« no previous file with comments | « tools/gn/loader.h ('k') | tools/gn/loader_unittest.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 "tools/gn/loader.h" 5 #include "tools/gn/loader.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "tools/gn/build_settings.h" 10 #include "tools/gn/build_settings.h"
11 #include "tools/gn/err.h" 11 #include "tools/gn/err.h"
12 #include "tools/gn/filesystem_utils.h" 12 #include "tools/gn/filesystem_utils.h"
13 #include "tools/gn/input_file_manager.h" 13 #include "tools/gn/input_file_manager.h"
14 #include "tools/gn/parse_tree.h" 14 #include "tools/gn/parse_tree.h"
15 #include "tools/gn/scheduler.h" 15 #include "tools/gn/scheduler.h"
16 #include "tools/gn/scope_per_file_provider.h" 16 #include "tools/gn/scope_per_file_provider.h"
17 #include "tools/gn/settings.h" 17 #include "tools/gn/settings.h"
18 #include "tools/gn/source_dir.h" 18 #include "tools/gn/source_dir.h"
19 #include "tools/gn/source_file.h" 19 #include "tools/gn/source_file.h"
20 #include "tools/gn/trace.h" 20 #include "tools/gn/trace.h"
21 21
22 namespace {
23
24 struct SourceFileAndOrigin {
25 SourceFileAndOrigin(const SourceFile& f, const LocationRange& o)
26 : file(f),
27 origin(o) {
28 }
29
30 SourceFile file;
31 LocationRange origin;
32 };
33
34 } // namespace
35
22 // Identifies one time a file is loaded in a given toolchain so we don't load 36 // Identifies one time a file is loaded in a given toolchain so we don't load
23 // it more than once. 37 // it more than once.
24 struct LoaderImpl::LoadID { 38 struct LoaderImpl::LoadID {
25 LoadID() {} 39 LoadID() {}
26 LoadID(const SourceFile& f, const Label& tc_name) 40 LoadID(const SourceFile& f, const Label& tc_name)
27 : file(f), 41 : file(f),
28 toolchain_name(tc_name) { 42 toolchain_name(tc_name) {
29 } 43 }
30 44
31 bool operator<(const LoadID& other) const { 45 bool operator<(const LoadID& other) const {
(...skipping 21 matching lines...) Expand all
53 is_config_loaded(false) { 67 is_config_loaded(false) {
54 settings.set_default_toolchain_label(default_toolchain_label); 68 settings.set_default_toolchain_label(default_toolchain_label);
55 settings.set_toolchain_label(toolchain_label); 69 settings.set_toolchain_label(toolchain_label);
56 } 70 }
57 71
58 Settings settings; 72 Settings settings;
59 73
60 bool is_toolchain_loaded; 74 bool is_toolchain_loaded;
61 bool is_config_loaded; 75 bool is_config_loaded;
62 76
63 std::vector<SourceFile> waiting_on_me; 77 std::vector<SourceFileAndOrigin> waiting_on_me;
64 }; 78 };
65 79
66 // ----------------------------------------------------------------------------- 80 // -----------------------------------------------------------------------------
67 81
68 const void* Loader::kDefaultToolchainKey = &kDefaultToolchainKey; 82 const void* Loader::kDefaultToolchainKey = &kDefaultToolchainKey;
69 83
70 Loader::Loader() { 84 Loader::Loader() {
71 } 85 }
72 86
73 Loader::~Loader() { 87 Loader::~Loader() {
74 } 88 }
75 89
76 void Loader::Load(const Label& label) { 90 void Loader::Load(const Label& label, const LocationRange& origin) {
77 Load(BuildFileForLabel(label), label.GetToolchainLabel()); 91 Load(BuildFileForLabel(label), origin, label.GetToolchainLabel());
78 } 92 }
79 93
80 // static 94 // static
81 SourceFile Loader::BuildFileForLabel(const Label& label) { 95 SourceFile Loader::BuildFileForLabel(const Label& label) {
82 return SourceFile(label.dir().value() + "BUILD.gn"); 96 return SourceFile(label.dir().value() + "BUILD.gn");
83 } 97 }
84 98
85 // ----------------------------------------------------------------------------- 99 // -----------------------------------------------------------------------------
86 100
87 LoaderImpl::LoaderImpl(const BuildSettings* build_settings) 101 LoaderImpl::LoaderImpl(const BuildSettings* build_settings)
88 : main_loop_(base::MessageLoop::current()), 102 : main_loop_(base::MessageLoop::current()),
89 pending_loads_(0), 103 pending_loads_(0),
90 build_settings_(build_settings) { 104 build_settings_(build_settings) {
91 } 105 }
92 106
93 LoaderImpl::~LoaderImpl() { 107 LoaderImpl::~LoaderImpl() {
94 STLDeleteContainerPairSecondPointers(toolchain_records_.begin(), 108 STLDeleteContainerPairSecondPointers(toolchain_records_.begin(),
95 toolchain_records_.end()); 109 toolchain_records_.end());
96 } 110 }
97 111
98 void LoaderImpl::Load(const SourceFile& file, 112 void LoaderImpl::Load(const SourceFile& file,
99 const Label& in_toolchain_name) { 113 const LocationRange& origin,
114 const Label& in_toolchain_name) {
100 const Label& toolchain_name = in_toolchain_name.is_null() 115 const Label& toolchain_name = in_toolchain_name.is_null()
101 ? default_toolchain_label_ : in_toolchain_name; 116 ? default_toolchain_label_ : in_toolchain_name;
102 LoadID load_id(file, toolchain_name); 117 LoadID load_id(file, toolchain_name);
103 if (!invocations_.insert(load_id).second) 118 if (!invocations_.insert(load_id).second)
104 return; // Already in set, so this file was already loaded or schedulerd. 119 return; // Already in set, so this file was already loaded or schedulerd.
105 120
106 if (toolchain_records_.empty()) { 121 if (toolchain_records_.empty()) {
107 // Nothing loaded, need to load the default build config. The intial load 122 // Nothing loaded, need to load the default build config. The intial load
108 // should not specify a toolchain. 123 // should not specify a toolchain.
109 DCHECK(toolchain_name.is_null()); 124 DCHECK(toolchain_name.is_null());
110 125
111 ToolchainRecord* record = 126 ToolchainRecord* record =
112 new ToolchainRecord(build_settings_, Label(), Label()); 127 new ToolchainRecord(build_settings_, Label(), Label());
113 toolchain_records_[Label()] = record; 128 toolchain_records_[Label()] = record;
114 129
115 // The default build config is no dependent on the toolchain definition, 130 // The default build config is no dependent on the toolchain definition,
116 // since we need to load the build config before we know what the default 131 // since we need to load the build config before we know what the default
117 // toolchain name is. 132 // toolchain name is.
118 record->is_toolchain_loaded = true; 133 record->is_toolchain_loaded = true;
119 134
120 record->waiting_on_me.push_back(file); 135 record->waiting_on_me.push_back(SourceFileAndOrigin(file, origin));
121 ScheduleLoadBuildConfig(&record->settings, Scope::KeyValueMap()); 136 ScheduleLoadBuildConfig(&record->settings, Scope::KeyValueMap());
122 return; 137 return;
123 } 138 }
124 139
125 ToolchainRecord* record; 140 ToolchainRecord* record;
126 if (toolchain_name.is_null()) 141 if (toolchain_name.is_null())
127 record = toolchain_records_[default_toolchain_label_]; 142 record = toolchain_records_[default_toolchain_label_];
128 else 143 else
129 record = toolchain_records_[toolchain_name]; 144 record = toolchain_records_[toolchain_name];
130 145
131 if (!record) { 146 if (!record) {
132 DCHECK(!default_toolchain_label_.is_null()); 147 DCHECK(!default_toolchain_label_.is_null());
133 148
134 // No reference to this toolchain found yet, make one. 149 // No reference to this toolchain found yet, make one.
135 record = new ToolchainRecord(build_settings_, toolchain_name, 150 record = new ToolchainRecord(build_settings_, toolchain_name,
136 default_toolchain_label_); 151 default_toolchain_label_);
137 toolchain_records_[toolchain_name] = record; 152 toolchain_records_[toolchain_name] = record;
138 153
139 // Schedule a load of the toolchain using the default one. 154 // Schedule a load of the toolchain using the default one.
140 Load(BuildFileForLabel(toolchain_name), default_toolchain_label_); 155 Load(BuildFileForLabel(toolchain_name), origin, default_toolchain_label_);
141 } 156 }
142 157
143 if (record->is_config_loaded) 158 if (record->is_config_loaded)
144 ScheduleLoadFile(&record->settings, file); 159 ScheduleLoadFile(&record->settings, origin, file);
145 else 160 else
146 record->waiting_on_me.push_back(file); 161 record->waiting_on_me.push_back(SourceFileAndOrigin(file, origin));
147 } 162 }
148 163
149 void LoaderImpl::ToolchainLoaded(const Toolchain* toolchain) { 164 void LoaderImpl::ToolchainLoaded(const Toolchain* toolchain) {
150 ToolchainRecord* record = toolchain_records_[toolchain->label()]; 165 ToolchainRecord* record = toolchain_records_[toolchain->label()];
151 if (!record) { 166 if (!record) {
152 DCHECK(!default_toolchain_label_.is_null()); 167 DCHECK(!default_toolchain_label_.is_null());
153 record = new ToolchainRecord(build_settings_, toolchain->label(), 168 record = new ToolchainRecord(build_settings_, toolchain->label(),
154 default_toolchain_label_); 169 default_toolchain_label_);
155 toolchain_records_[toolchain->label()] = record; 170 toolchain_records_[toolchain->label()] = record;
156 } 171 }
(...skipping 24 matching lines...) Expand all
181 } else { 196 } else {
182 found_toolchain = toolchain_records_.find(label); 197 found_toolchain = toolchain_records_.find(label);
183 } 198 }
184 199
185 if (found_toolchain == toolchain_records_.end()) 200 if (found_toolchain == toolchain_records_.end())
186 return NULL; 201 return NULL;
187 return &found_toolchain->second->settings; 202 return &found_toolchain->second->settings;
188 } 203 }
189 204
190 void LoaderImpl::ScheduleLoadFile(const Settings* settings, 205 void LoaderImpl::ScheduleLoadFile(const Settings* settings,
206 const LocationRange& origin,
191 const SourceFile& file) { 207 const SourceFile& file) {
192 Err err; 208 Err err;
193 pending_loads_++; 209 pending_loads_++;
194 if (!AsyncLoadFile(LocationRange(), settings->build_settings(), file, 210 if (!AsyncLoadFile(origin, settings->build_settings(), file,
195 base::Bind(&LoaderImpl::BackgroundLoadFile, this, 211 base::Bind(&LoaderImpl::BackgroundLoadFile, this,
196 settings, file), 212 settings, file),
197 &err)) { 213 &err)) {
198 g_scheduler->FailWithError(err); 214 g_scheduler->FailWithError(err);
199 DecrementPendingLoads(); 215 DecrementPendingLoads();
200 } 216 }
201 } 217 }
202 218
203 void LoaderImpl::ScheduleLoadBuildConfig( 219 void LoaderImpl::ScheduleLoadBuildConfig(
204 Settings* settings, 220 Settings* settings,
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 } 383 }
368 } else { 384 } else {
369 record = found_toolchain->second; 385 record = found_toolchain->second;
370 } 386 }
371 387
372 DCHECK(!record->is_config_loaded); 388 DCHECK(!record->is_config_loaded);
373 DCHECK(record->is_toolchain_loaded); 389 DCHECK(record->is_toolchain_loaded);
374 record->is_config_loaded = true; 390 record->is_config_loaded = true;
375 391
376 // Schedule all waiting file loads. 392 // Schedule all waiting file loads.
377 for (size_t i = 0; i < record->waiting_on_me.size(); i++) 393 for (size_t i = 0; i < record->waiting_on_me.size(); i++) {
378 ScheduleLoadFile(&record->settings, record->waiting_on_me[i]); 394 ScheduleLoadFile(&record->settings, record->waiting_on_me[i].origin,
395 record->waiting_on_me[i].file);
396 }
379 record->waiting_on_me.clear(); 397 record->waiting_on_me.clear();
380 398
381 DecrementPendingLoads(); 399 DecrementPendingLoads();
382 } 400 }
383 401
384 void LoaderImpl::DecrementPendingLoads() { 402 void LoaderImpl::DecrementPendingLoads() {
385 DCHECK(pending_loads_ > 0); 403 DCHECK(pending_loads_ > 0);
386 pending_loads_--; 404 pending_loads_--;
387 if (pending_loads_ == 0 && !complete_callback_.is_null()) 405 if (pending_loads_ == 0 && !complete_callback_.is_null())
388 complete_callback_.Run(); 406 complete_callback_.Run();
389 } 407 }
390 408
391 bool LoaderImpl::AsyncLoadFile( 409 bool LoaderImpl::AsyncLoadFile(
392 const LocationRange& origin, 410 const LocationRange& origin,
393 const BuildSettings* build_settings, 411 const BuildSettings* build_settings,
394 const SourceFile& file_name, 412 const SourceFile& file_name,
395 const base::Callback<void(const ParseNode*)>& callback, 413 const base::Callback<void(const ParseNode*)>& callback,
396 Err* err) { 414 Err* err) {
397 if (async_load_file_.is_null()) { 415 if (async_load_file_.is_null()) {
398 return g_scheduler->input_file_manager()->AsyncLoadFile( 416 return g_scheduler->input_file_manager()->AsyncLoadFile(
399 origin, build_settings, file_name, callback, err); 417 origin, build_settings, file_name, callback, err);
400 } 418 }
401 return async_load_file_.Run( 419 return async_load_file_.Run(
402 origin, build_settings, file_name, callback, err); 420 origin, build_settings, file_name, callback, err);
403 } 421 }
OLDNEW
« no previous file with comments | « tools/gn/loader.h ('k') | tools/gn/loader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698