| 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 |