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

Side by Side Diff: tools/gn/scope.h

Issue 21114002: Add initial prototype for the GN meta-buildsystem. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add owners and readme Created 7 years, 4 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/scheduler.cc ('k') | tools/gn/scope.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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_SCOPE_H_
6 #define TOOLS_GN_SCOPE_H_
7
8 #include <map>
9 #include <set>
10
11 #include "base/basictypes.h"
12 #include "base/containers/hash_tables.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "tools/gn/err.h"
15 #include "tools/gn/pattern.h"
16 #include "tools/gn/value.h"
17
18 class FunctionCallNode;
19 class ImportManager;
20 class ParseNode;
21 class Settings;
22 class TargetManager;
23
24 // Scope for the script execution.
25 //
26 // Scopes are nested. Writing goes into the toplevel scope, reading checks
27 // values resursively down the stack until a match is found or there are no
28 // more containing scopes.
29 //
30 // A containing scope can be const or non-const. The const containing scope is
31 // used primarily to refer to the master build config which is shared across
32 // many invocations. A const containing scope, however, prevents us from
33 // marking variables "used" which prevents us from issuing errors on unused
34 // variables. So you should use a non-const containing scope whenever possible.
35 class Scope {
36 public:
37 typedef std::vector<std::pair<base::StringPiece, Value> > KeyValueVector;
38
39 // Allows code to provide values for built-in variables. This class will
40 // automatically register itself on construction and deregister itself on
41 // destruction.
42 class ProgrammaticProvider {
43 public:
44 ProgrammaticProvider(Scope* scope) : scope_(scope) {
45 scope_->AddProvider(this);
46 }
47 ~ProgrammaticProvider() {
48 scope_->RemoveProvider(this);
49 }
50
51 // Returns a non-null value if the given value can be programmatically
52 // generated, or NULL if there is none.
53 virtual const Value* GetProgrammaticValue(
54 const base::StringPiece& ident) = 0;
55
56 protected:
57 Scope* scope_;
58 };
59
60 // Creates an empty toplevel scope.
61 Scope(const Settings* settings);
62
63 // Creates a dependent scope.
64 Scope(Scope* parent);
65 Scope(const Scope* parent);
66
67 ~Scope();
68
69 const Settings* settings() const { return settings_; }
70
71 // See the const_/mutable_containing_ var declaraions below. Yes, it's a
72 // bit weird that we can have a const pointer to the "mutable" one.
73 Scope* mutable_containing() { return mutable_containing_; }
74 const Scope* mutable_containing() const { return mutable_containing_; }
75 const Scope* const_containing() const { return const_containing_; }
76 const Scope* containing() const {
77 return mutable_containing_ ? mutable_containing_ : const_containing_;
78 }
79
80 // Returns NULL if there's no such value.
81 //
82 // counts_as_used should be set if the variable is being read in a way that
83 // should count for unused variable checking.
84 const Value* GetValue(const base::StringPiece& ident,
85 bool counts_as_used);
86 const Value* GetValue(const base::StringPiece& ident) const;
87
88 // Same as GetValue, but if the value exists in a parent scope, we'll copy
89 // it to the current scope. If the return value is non-null, the value is
90 // guaranteed to be set in the current scope. Generatlly this will be used
91 // if the calling code is planning on modifying the value in-place.
92 //
93 // Since this is used when doing read-modifies, we never count this access
94 // as reading the variable, since we assume it will be written to.
95 Value* GetValueForcedToCurrentScope(const base::StringPiece& ident,
96 const ParseNode* set_node);
97
98 // The set_node indicates the statement that caused the set, for displaying
99 // errors later. Returns a pointer to the value in the current scope (a copy
100 // is made for storage).
101 Value* SetValue(const base::StringPiece& ident,
102 const Value& v,
103 const ParseNode* set_node);
104
105 // Templates associated with this scope. A template can only be set once, so
106 // AddTemplate will fail and return NULL if a rule with that name already
107 // exists. GetTemplate returns NULL if the rule doesn't exist, and it will
108 // check all containing scoped rescursively.
109 bool AddTemplate(const std::string& name, const FunctionCallNode* decl);
110 const FunctionCallNode* GetTemplate(const std::string& name) const;
111
112 // Marks the given identifier as (un)used in the current scope.
113 void MarkUsed(const base::StringPiece& ident);
114 void MarkUnused(const base::StringPiece& ident);
115
116 // Checks to see if the scope has a var set that hasn't been used. This is
117 // called before replacing the var with a different one. It does not check
118 // containing scopes.
119 //
120 // If the identifier is present but hasnn't been used, return true.
121 bool IsSetButUnused(const base::StringPiece& ident) const;
122
123 // Checks the scope to see if any values were set but not used, and fills in
124 // the error and returns false if they were.
125 bool CheckForUnusedVars(Err* err) const;
126
127 // Returns all values set in the current scope, without going to the parent
128 // scopes.
129 void GetCurrentScopeValues(KeyValueVector* output) const;
130
131 // Copies this scope's values into the destination. Values from the
132 // containing scope(s) (normally shadowed into the current one) will not be
133 // copied, neither will the reference to the containing scope (this is why
134 // it's "non-recursive").
135 //
136 // It is an error to merge a variable into a scope that already has something
137 // with that name in scope (meaning in that scope or in any of its containing
138 // scopes). If this happens, the error will be set and the function will
139 // return false.
140 //
141 // This is used in different contexts. When generating the error, the given
142 // parse node will be blamed, and the given desc will be used to describe
143 // the operation that doesn't support doing this. For example, desc_for_err
144 // would be "import" when doing an import, and the error string would say
145 // something like "The import contains...".
146 bool NonRecursiveMergeTo(Scope* dest,
147 const ParseNode* node_for_err,
148 const char* desc_for_err,
149 Err* err) const;
150
151 // Makes an empty scope with the given name. Returns NULL if the name is
152 // already set.
153 Scope* MakeTargetDefaults(const std::string& target_type);
154
155 // Gets the scope associated with the given target name, or null if it hasn't
156 // been set.
157 const Scope* GetTargetDefaults(const std::string& target_type) const;
158
159 // Filter to apply when the sources variable is assigned. May return NULL.
160 const PatternList* GetSourcesAssignmentFilter() const;
161 void set_sources_assignment_filter(
162 scoped_ptr<PatternList> f) {
163 sources_assignment_filter_ = f.Pass();
164 }
165
166 // Indicates if we're currently processing the build configuration file.
167 // This is true when processing the config file for any toolchain. See also
168 // *ProcessingDefaultBuildConfig() below.
169 //
170 // To set or clear the flag, it must currently be in the opposite state in
171 // the current scope. Note that querying the state of the flag recursively
172 // checks all containing scopes until it reaches the top or finds the flag
173 // set.
174 void SetProcessingBuildConfig();
175 void ClearProcessingBuildConfig();
176 bool IsProcessingBuildConfig() const;
177
178 // Indicates we're currently processing the default toolchain's build
179 // configuration file.
180 void SetProcessingDefaultBuildConfig();
181 void ClearProcessingDefaultBuildConfig();
182 bool IsProcessingDefaultBuildConfig() const;
183
184 // Indicates if we're currently processing an import file.
185 //
186 // See SetProcessingBaseConfig for how flags work.
187 void SetProcessingImport();
188 void ClearProcessingImport();
189 bool IsProcessingImport() const;
190
191 // Properties are opaque pointers that code can use to set state on a Scope
192 // that it can retrieve later.
193 //
194 // The key should be a pointer to some use-case-specific object (to avoid
195 // collisions, otherwise it doesn't matter). Memory management is up to the
196 // setter. Setting the value to NULL will delete the property.
197 //
198 // Getting a property recursively searches all scopes, and the optional
199 // |found_on_scope| variable will be filled with the actual scope containing
200 // the key (if the pointer is non-NULL).
201 void SetProperty(const void* key, void* value);
202 void* GetProperty(const void* key, const Scope** found_on_scope) const;
203
204 private:
205 friend class ProgrammaticProvider;
206
207 struct Record {
208 Record() : used(false) {}
209 Record(const Value& v) : used(false), value(v) {}
210
211 bool used; // Set to true when the variable is used.
212 Value value;
213 };
214
215 void AddProvider(ProgrammaticProvider* p);
216 void RemoveProvider(ProgrammaticProvider* p);
217
218 // Scopes can have no containing scope (both null), a mutable containing
219 // scope, or a const containing scope. The reason is that when we're doing
220 // a new target, we want to refer to the base_config scope which will be read
221 // by multiple threads at the same time, so we REALLY want it to be const.
222 // When you jsut do a nested {}, however, we sometimes want to be able to
223 // change things (especially marking unused vars).
224 const Scope* const_containing_;
225 Scope* mutable_containing_;
226
227 const Settings* settings_;
228
229 // Bits set for different modes. See the flag definitions in the .cc file
230 // for more.
231 unsigned mode_flags_;
232
233 typedef base::hash_map<base::StringPiece, Record> RecordMap;
234 RecordMap values_;
235
236 // Owning pointers. Note that this can't use string pieces since the names
237 // are constructed from Values which might be deallocated before this goes
238 // out of scope.
239 typedef base::hash_map<std::string, Scope*> NamedScopeMap;
240 NamedScopeMap target_defaults_;
241
242 // Null indicates not set and that we should fallback to the containing
243 // scope's filter.
244 scoped_ptr<PatternList> sources_assignment_filter_;
245
246 // Non-owning pointers, the function calls are owned by the input file which
247 // should be kept around by the input file manager.
248 typedef std::map<std::string, const FunctionCallNode*> TemplateMap;
249 TemplateMap templates_;
250
251 typedef std::map<const void*, void*> PropertyMap;
252 PropertyMap properties_;
253
254 typedef std::set<ProgrammaticProvider*> ProviderSet;
255 ProviderSet programmatic_providers_;
256
257 DISALLOW_COPY_AND_ASSIGN(Scope);
258 };
259
260 #endif // TOOLS_GN_SCOPE_H_
OLDNEW
« no previous file with comments | « tools/gn/scheduler.cc ('k') | tools/gn/scope.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698