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
3 // found in the LICENSE file.
5 #include "tools/gn/item_node.h"
9 #include "base/callback.h"
10 #include "base/logging.h"
11 #include "tools/gn/build_settings.h"
12 #include "tools/gn/item.h"
14 ItemNode::ItemNode(Item
* i
)
17 should_generate_(false) {
18 item_
->set_item_node(this);
21 ItemNode::~ItemNode() {
24 bool ItemNode::SetShouldGenerate(const BuildSettings
* build_settings
,
28 should_generate_
= true;
30 if (state_
== DEFINED
) {
31 if (!ScheduleDepsLoad(build_settings
, err
))
33 } else if (state_
== RESOLVED
) {
34 // The item may have been resolved even if we didn't set the generate bit
35 // if all of its deps were loaded some other way. In this case, we need
36 // to run the closure which we skipped when it became resolved.
37 if (!resolved_closure_
.is_null())
38 resolved_closure_
.Run();
41 // Pass the generate bit to all deps.
42 for (ItemNodeMap::iterator i
= direct_dependencies_
.begin();
43 i
!= direct_dependencies_
.end(); ++i
) {
44 if (!i
->first
->SetShouldGenerate(build_settings
, err
))
50 bool ItemNode::AddDependency(const BuildSettings
* build_settings
,
51 const LocationRange
& specified_from_here
,
54 // Can't add more deps once it's been defined.
55 DCHECK(state_
== REFERENCED
);
57 if (direct_dependencies_
.find(node
) != direct_dependencies_
.end())
58 return true; // Already have this dep.
60 direct_dependencies_
[node
] = specified_from_here
;
62 if (node
->state() != RESOLVED
) {
63 // Wire up the pending resolution info.
64 unresolved_dependencies_
[node
] = specified_from_here
;
65 node
->waiting_on_resolution_
[this] = specified_from_here
;
68 if (should_generate_
) {
69 if (!node
->SetShouldGenerate(build_settings
, err
))
75 void ItemNode::MarkDirectDependencyResolved(ItemNode
* node
) {
76 DCHECK(unresolved_dependencies_
.find(node
) != unresolved_dependencies_
.end());
77 unresolved_dependencies_
.erase(node
);
80 void ItemNode::SwapOutWaitingDependencySet(ItemNodeMap
* out_map
) {
81 waiting_on_resolution_
.swap(*out_map
);
82 DCHECK(waiting_on_resolution_
.empty());
85 bool ItemNode::SetDefined(const BuildSettings
* build_settings
, Err
* err
) {
86 DCHECK(state_
== REFERENCED
);
90 return ScheduleDepsLoad(build_settings
, err
);
94 void ItemNode::SetResolved() {
95 DCHECK(state_
!= RESOLVED
);
98 if (should_generate_
&& !resolved_closure_
.is_null())
99 resolved_closure_
.Run();
102 bool ItemNode::ScheduleDepsLoad(const BuildSettings
* build_settings
,
104 DCHECK(state_
== DEFINED
);
105 DCHECK(should_generate_
); // Shouldn't be requesting deps for ungenerated
108 for (ItemNodeMap::const_iterator i
= unresolved_dependencies_
.begin();
109 i
!= unresolved_dependencies_
.end(); ++i
) {
110 Label toolchain_label
= i
->first
->item()->label().GetToolchainLabel();
111 SourceDir dir_to_load
= i
->first
->item()->label().dir();
113 if (!build_settings
->toolchain_manager().ScheduleInvocationLocked(
114 i
->second
, toolchain_label
, dir_to_load
, err
))
118 state_
= PENDING_DEPS
;