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.
4
5#ifndef TOOLS_GN_BUILDER_RECORD_H_
6#define TOOLS_GN_BUILDER_RECORD_H_
7
8#include <set>
9
10#include "base/basictypes.h"
11#include "base/memory/scoped_ptr.h"
12#include "tools/gn/item.h"
13#include "tools/gn/location.h"
14
15class ParseNode;
16
17// This class is used by the builder to manage the loading of the dependency
18// tree. It holds a reference to an item and links to other records that the
19// item depends on, both resolved ones, and unresolved ones.
20//
21// If a target depends on another one that hasn't been defined yet, we'll make
22// a placeholder BuilderRecord with no item, and try to load the buildfile
23// associated with the new item. The item will get filled in when we encounter
24// the declaration for the item (or when we're done and realize there are
25// undefined items).
26//
27// You can also have null item pointers when the target is not required for
28// the current build (should_generate is false).
29class BuilderRecord {
30 public:
31  typedef std::set<BuilderRecord*> BuilderRecordSet;
32
33  enum ItemType {
34    ITEM_UNKNOWN,
35    ITEM_TARGET,
36    ITEM_CONFIG,
37    ITEM_TOOLCHAIN
38  };
39
40  //BuilderRecord();
41  BuilderRecord(ItemType type, const Label& label);
42  ~BuilderRecord();
43
44  ItemType type() const { return type_; }
45  const Label& label() const { return label_; }
46
47  // Returns a user-ready name for the given type. e.g. "target".
48  static const char* GetNameForType(ItemType type);
49
50  // Returns true if the given item is of the given type.
51  static bool IsItemOfType(const Item* item, ItemType type);
52
53  // Returns the type enum for the given item.
54  static ItemType TypeOfItem(const Item* item);
55
56  Item* item() { return item_.get(); }
57  const Item* item() const { return item_.get(); }
58  void set_item(scoped_ptr<Item> item) { item_ = item.Pass(); }
59
60  // Indicates from where this item was originally referenced from that caused
61  // it to be loaded. For targets for which we encountered the declaration
62  // before a reference, this will be the empty range.
63  const ParseNode* originally_referenced_from() const {
64    return originally_referenced_from_;
65  }
66  void set_originally_referenced_from(const ParseNode* pn) {
67    originally_referenced_from_ = pn;
68  }
69
70  bool should_generate() const { return should_generate_; }
71  void set_should_generate(bool sg) { should_generate_ = sg; }
72
73  bool resolved() const { return resolved_; }
74  void set_resolved(bool r) { resolved_ = r; }
75
76  bool can_resolve() const {
77    return item_ && unresolved_deps_.empty();
78  }
79
80  // All records this one is depending on.
81  BuilderRecordSet& all_deps() { return all_deps_; }
82  const BuilderRecordSet& all_deps() const { return all_deps_; }
83
84  // Unresolved records this one is depending on. A subset of all... above.
85  BuilderRecordSet& unresolved_deps() { return unresolved_deps_; }
86  const BuilderRecordSet& unresolved_deps() const { return unresolved_deps_; }
87
88  // Records that are waiting on this one to be resolved. This is the other
89  // end of the "unresolved deps" arrow.
90  BuilderRecordSet& waiting_on_resolution() { return waiting_on_resolution_; }
91  const BuilderRecordSet& waiting_on_resolution() const {
92    return waiting_on_resolution_;
93  }
94
95  void AddDep(BuilderRecord* record);
96
97 private:
98  ItemType type_;
99  Label label_;
100  scoped_ptr<Item> item_;
101  const ParseNode* originally_referenced_from_;
102  bool should_generate_;
103  bool resolved_;
104
105  BuilderRecordSet all_deps_;
106  BuilderRecordSet unresolved_deps_;
107  BuilderRecordSet waiting_on_resolution_;
108
109  DISALLOW_COPY_AND_ASSIGN(BuilderRecord);
110};
111
112#endif  // TOOLS_GN_BUILDER_RECORD_H_
113