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/loader.h" | 5 #include "tools/gn/loader.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/stl_util.h" | |
11 #include "tools/gn/build_settings.h" | 10 #include "tools/gn/build_settings.h" |
12 #include "tools/gn/err.h" | 11 #include "tools/gn/err.h" |
13 #include "tools/gn/filesystem_utils.h" | 12 #include "tools/gn/filesystem_utils.h" |
14 #include "tools/gn/input_file_manager.h" | 13 #include "tools/gn/input_file_manager.h" |
15 #include "tools/gn/parse_tree.h" | 14 #include "tools/gn/parse_tree.h" |
16 #include "tools/gn/scheduler.h" | 15 #include "tools/gn/scheduler.h" |
17 #include "tools/gn/scope_per_file_provider.h" | 16 #include "tools/gn/scope_per_file_provider.h" |
18 #include "tools/gn/settings.h" | 17 #include "tools/gn/settings.h" |
19 #include "tools/gn/source_dir.h" | 18 #include "tools/gn/source_dir.h" |
20 #include "tools/gn/source_file.h" | 19 #include "tools/gn/source_file.h" |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 | 98 |
100 // ----------------------------------------------------------------------------- | 99 // ----------------------------------------------------------------------------- |
101 | 100 |
102 LoaderImpl::LoaderImpl(const BuildSettings* build_settings) | 101 LoaderImpl::LoaderImpl(const BuildSettings* build_settings) |
103 : main_loop_(base::MessageLoop::current()), | 102 : main_loop_(base::MessageLoop::current()), |
104 pending_loads_(0), | 103 pending_loads_(0), |
105 build_settings_(build_settings) { | 104 build_settings_(build_settings) { |
106 } | 105 } |
107 | 106 |
108 LoaderImpl::~LoaderImpl() { | 107 LoaderImpl::~LoaderImpl() { |
109 STLDeleteContainerPairSecondPointers(toolchain_records_.begin(), | |
110 toolchain_records_.end()); | |
111 } | 108 } |
112 | 109 |
113 void LoaderImpl::Load(const SourceFile& file, | 110 void LoaderImpl::Load(const SourceFile& file, |
114 const LocationRange& origin, | 111 const LocationRange& origin, |
115 const Label& in_toolchain_name) { | 112 const Label& in_toolchain_name) { |
116 const Label& toolchain_name = in_toolchain_name.is_null() | 113 const Label& toolchain_name = in_toolchain_name.is_null() |
117 ? default_toolchain_label_ : in_toolchain_name; | 114 ? default_toolchain_label_ : in_toolchain_name; |
118 LoadID load_id(file, toolchain_name); | 115 LoadID load_id(file, toolchain_name); |
119 if (!invocations_.insert(load_id).second) | 116 if (!invocations_.insert(load_id).second) |
120 return; // Already in set, so this file was already loaded or schedulerd. | 117 return; // Already in set, so this file was already loaded or schedulerd. |
121 | 118 |
122 if (toolchain_records_.empty()) { | 119 if (toolchain_records_.empty()) { |
123 // Nothing loaded, need to load the default build config. The intial load | 120 // Nothing loaded, need to load the default build config. The initial load |
124 // should not specify a toolchain. | 121 // should not specify a toolchain. |
125 DCHECK(toolchain_name.is_null()); | 122 DCHECK(toolchain_name.is_null()); |
126 | 123 |
127 ToolchainRecord* record = | 124 std::unique_ptr<ToolchainRecord> new_record( |
128 new ToolchainRecord(build_settings_, Label(), Label()); | 125 new ToolchainRecord(build_settings_, Label(), Label())); |
129 toolchain_records_[Label()] = record; | 126 ToolchainRecord* record = new_record.get(); |
| 127 toolchain_records_[Label()] = std::move(new_record); |
130 | 128 |
131 // The default build config is no dependent on the toolchain definition, | 129 // The default build config is no dependent on the toolchain definition, |
132 // since we need to load the build config before we know what the default | 130 // since we need to load the build config before we know what the default |
133 // toolchain name is. | 131 // toolchain name is. |
134 record->is_toolchain_loaded = true; | 132 record->is_toolchain_loaded = true; |
135 | 133 |
136 record->waiting_on_me.push_back(SourceFileAndOrigin(file, origin)); | 134 record->waiting_on_me.push_back(SourceFileAndOrigin(file, origin)); |
137 ScheduleLoadBuildConfig(&record->settings, Scope::KeyValueMap()); | 135 ScheduleLoadBuildConfig(&record->settings, Scope::KeyValueMap()); |
| 136 |
138 return; | 137 return; |
139 } | 138 } |
140 | 139 |
141 ToolchainRecord* record; | 140 ToolchainRecord* record; |
142 if (toolchain_name.is_null()) | 141 if (toolchain_name.is_null()) |
143 record = toolchain_records_[default_toolchain_label_]; | 142 record = toolchain_records_[default_toolchain_label_].get(); |
144 else | 143 else |
145 record = toolchain_records_[toolchain_name]; | 144 record = toolchain_records_[toolchain_name].get(); |
146 | 145 |
147 if (!record) { | 146 if (!record) { |
148 DCHECK(!default_toolchain_label_.is_null()); | 147 DCHECK(!default_toolchain_label_.is_null()); |
149 | 148 |
150 // No reference to this toolchain found yet, make one. | 149 // No reference to this toolchain found yet, make one. |
151 record = new ToolchainRecord(build_settings_, toolchain_name, | 150 std::unique_ptr<ToolchainRecord> new_record(new ToolchainRecord( |
152 default_toolchain_label_); | 151 build_settings_, toolchain_name, default_toolchain_label_)); |
153 toolchain_records_[toolchain_name] = record; | 152 record = new_record.get(); |
| 153 toolchain_records_[toolchain_name] = std::move(new_record); |
154 | 154 |
155 // Schedule a load of the toolchain using the default one. | 155 // Schedule a load of the toolchain using the default one. |
156 Load(BuildFileForLabel(toolchain_name), origin, default_toolchain_label_); | 156 Load(BuildFileForLabel(toolchain_name), origin, default_toolchain_label_); |
157 } | 157 } |
158 | 158 |
159 if (record->is_config_loaded) | 159 if (record->is_config_loaded) |
160 ScheduleLoadFile(&record->settings, origin, file); | 160 ScheduleLoadFile(&record->settings, origin, file); |
161 else | 161 else |
162 record->waiting_on_me.push_back(SourceFileAndOrigin(file, origin)); | 162 record->waiting_on_me.push_back(SourceFileAndOrigin(file, origin)); |
163 } | 163 } |
164 | 164 |
165 void LoaderImpl::ToolchainLoaded(const Toolchain* toolchain) { | 165 void LoaderImpl::ToolchainLoaded(const Toolchain* toolchain) { |
166 ToolchainRecord* record = toolchain_records_[toolchain->label()]; | 166 ToolchainRecord* record = toolchain_records_[toolchain->label()].get(); |
167 if (!record) { | 167 if (!record) { |
168 DCHECK(!default_toolchain_label_.is_null()); | 168 DCHECK(!default_toolchain_label_.is_null()); |
169 record = new ToolchainRecord(build_settings_, toolchain->label(), | 169 std::unique_ptr<ToolchainRecord> new_record(new ToolchainRecord( |
170 default_toolchain_label_); | 170 build_settings_, toolchain->label(), default_toolchain_label_)); |
171 toolchain_records_[toolchain->label()] = record; | 171 record = new_record.get(); |
| 172 toolchain_records_[toolchain->label()] = std::move(new_record); |
172 } | 173 } |
173 record->is_toolchain_loaded = true; | 174 record->is_toolchain_loaded = true; |
174 | 175 |
175 // The default build config is loaded first, then its toolchain. Secondary | 176 // The default build config is loaded first, then its toolchain. Secondary |
176 // ones are loaded in the opposite order so we can pass toolchain parameters | 177 // ones are loaded in the opposite order so we can pass toolchain parameters |
177 // to the build config. So we may or may not have a config at this point. | 178 // to the build config. So we may or may not have a config at this point. |
178 if (!record->is_config_loaded) { | 179 if (!record->is_config_loaded) { |
179 ScheduleLoadBuildConfig(&record->settings, toolchain->args()); | 180 ScheduleLoadBuildConfig(&record->settings, toolchain->args()); |
180 } else { | 181 } else { |
181 // There should be nobody waiting on this if the build config is already | 182 // There should be nobody waiting on this if the build config is already |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 // When loading the default build config, we'll insert it into the record | 350 // When loading the default build config, we'll insert it into the record |
350 // map with an empty label since we don't yet know what to call it. | 351 // map with an empty label since we don't yet know what to call it. |
351 // | 352 // |
352 // In this case, we should have exactly one entry in the map with an empty | 353 // In this case, we should have exactly one entry in the map with an empty |
353 // label. We now need to fix up the naming so it refers to the "real" one. | 354 // label. We now need to fix up the naming so it refers to the "real" one. |
354 CHECK_EQ(1U, toolchain_records_.size()); | 355 CHECK_EQ(1U, toolchain_records_.size()); |
355 ToolchainRecordMap::iterator empty_label = toolchain_records_.find(Label()); | 356 ToolchainRecordMap::iterator empty_label = toolchain_records_.find(Label()); |
356 CHECK(empty_label != toolchain_records_.end()); | 357 CHECK(empty_label != toolchain_records_.end()); |
357 | 358 |
358 // Fix up the toolchain record. | 359 // Fix up the toolchain record. |
359 record = empty_label->second; | 360 std::unique_ptr<ToolchainRecord> moved_record = |
360 toolchain_records_[label] = record; | 361 std::move(empty_label->second); |
| 362 record = moved_record.get(); |
| 363 toolchain_records_[label] = std::move(moved_record); |
361 toolchain_records_.erase(empty_label); | 364 toolchain_records_.erase(empty_label); |
362 | 365 |
363 // Save the default toolchain label. | 366 // Save the default toolchain label. |
364 default_toolchain_label_ = label; | 367 default_toolchain_label_ = label; |
365 DCHECK(record->settings.default_toolchain_label().is_null()); | 368 DCHECK(record->settings.default_toolchain_label().is_null()); |
366 record->settings.set_default_toolchain_label(label); | 369 record->settings.set_default_toolchain_label(label); |
367 | 370 |
368 // The settings object should have the toolchain label already set. | 371 // The settings object should have the toolchain label already set. |
369 DCHECK(!record->settings.toolchain_label().is_null()); | 372 DCHECK(!record->settings.toolchain_label().is_null()); |
370 | 373 |
371 // Update any stored invocations that refer to the empty toolchain label. | 374 // Update any stored invocations that refer to the empty toolchain label. |
372 // This will normally only be one, for the root build file, so brute-force | 375 // This will normally only be one, for the root build file, so brute-force |
373 // is OK. | 376 // is OK. |
374 LoadIDSet old_loads; | 377 LoadIDSet old_loads; |
375 invocations_.swap(old_loads); | 378 invocations_.swap(old_loads); |
376 for (const auto& load : old_loads) { | 379 for (const auto& load : old_loads) { |
377 if (load.toolchain_name.is_null()) { | 380 if (load.toolchain_name.is_null()) { |
378 // Fix up toolchain label | 381 // Fix up toolchain label |
379 invocations_.insert(LoadID(load.file, label)); | 382 invocations_.insert(LoadID(load.file, label)); |
380 } else { | 383 } else { |
381 // Can keep the old one. | 384 // Can keep the old one. |
382 invocations_.insert(load); | 385 invocations_.insert(load); |
383 } | 386 } |
384 } | 387 } |
385 } else { | 388 } else { |
386 record = found_toolchain->second; | 389 record = found_toolchain->second.get(); |
387 } | 390 } |
388 | 391 |
389 DCHECK(!record->is_config_loaded); | 392 DCHECK(!record->is_config_loaded); |
390 DCHECK(record->is_toolchain_loaded); | 393 DCHECK(record->is_toolchain_loaded); |
391 record->is_config_loaded = true; | 394 record->is_config_loaded = true; |
392 | 395 |
393 // Schedule all waiting file loads. | 396 // Schedule all waiting file loads. |
394 for (const auto& waiting : record->waiting_on_me) | 397 for (const auto& waiting : record->waiting_on_me) |
395 ScheduleLoadFile(&record->settings, waiting.origin, waiting.file); | 398 ScheduleLoadFile(&record->settings, waiting.origin, waiting.file); |
396 record->waiting_on_me.clear(); | 399 record->waiting_on_me.clear(); |
(...skipping 14 matching lines...) Expand all Loading... |
411 const SourceFile& file_name, | 414 const SourceFile& file_name, |
412 const base::Callback<void(const ParseNode*)>& callback, | 415 const base::Callback<void(const ParseNode*)>& callback, |
413 Err* err) { | 416 Err* err) { |
414 if (async_load_file_.is_null()) { | 417 if (async_load_file_.is_null()) { |
415 return g_scheduler->input_file_manager()->AsyncLoadFile( | 418 return g_scheduler->input_file_manager()->AsyncLoadFile( |
416 origin, build_settings, file_name, callback, err); | 419 origin, build_settings, file_name, callback, err); |
417 } | 420 } |
418 return async_load_file_.Run( | 421 return async_load_file_.Run( |
419 origin, build_settings, file_name, callback, err); | 422 origin, build_settings, file_name, callback, err); |
420 } | 423 } |
OLD | NEW |