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 <memory> 10 #include <set> 11 #include <string> 12 #include <string_view> 13 #include <unordered_map> 14 #include <utility> 15 #include <vector> 16 17 #include "base/memory/ref_counted.h" 18 #include "gn/err.h" 19 #include "gn/location.h" 20 #include "gn/pattern.h" 21 #include "gn/source_dir.h" 22 #include "gn/source_file.h" 23 #include "gn/value.h" 24 25 class Item; 26 class ParseNode; 27 class Settings; 28 class Template; 29 30 // Scope for the script execution. 31 // 32 // Scopes are nested. Writing goes into the toplevel scope, reading checks 33 // values recursively down the stack until a match is found or there are no 34 // more containing scopes. 35 // 36 // A containing scope can be const or non-const. The const containing scope is 37 // used primarily to refer to the master build config which is shared across 38 // many invocations. A const containing scope, however, prevents us from 39 // marking variables "used" which prevents us from issuing errors on unused 40 // variables. So you should use a non-const containing scope whenever possible. 41 class Scope { 42 public: 43 using KeyValueMap = std::map<std::string_view, Value>; 44 // Holds an owning list of Items. 45 using ItemVector = std::vector<std::unique_ptr<Item>>; 46 47 // A flag to indicate whether a function should recurse into nested scopes, 48 // or only operate on the current scope. 49 enum SearchNested { SEARCH_NESTED, SEARCH_CURRENT }; 50 51 // Allows code to provide values for built-in variables. This class will 52 // automatically register itself on construction and deregister itself on 53 // destruction. 54 class ProgrammaticProvider { 55 public: ProgrammaticProvider(Scope * scope)56 explicit ProgrammaticProvider(Scope* scope) : scope_(scope) { 57 scope_->AddProvider(this); 58 } 59 virtual ~ProgrammaticProvider(); 60 61 // Returns a non-null value if the given value can be programmatically 62 // generated, or NULL if there is none. 63 virtual const Value* GetProgrammaticValue(std::string_view ident) = 0; 64 65 protected: 66 Scope* scope_; 67 }; 68 69 // Options for configuring scope merges. 70 struct MergeOptions { 71 MergeOptions(); 72 ~MergeOptions(); 73 74 // When set, all existing avlues in the destination scope will be 75 // overwritten. 76 // 77 // When false, it will be an error to merge a variable into another scope 78 // where a variable with the same name is already set. The exception is 79 // if both of the variables have the same value (which happens if you 80 // somehow multiply import the same file, for example). This case will be 81 // ignored since there is nothing getting lost. 82 bool clobber_existing; 83 84 // When true, private variables (names beginning with an underscore) will 85 // be copied to the destination scope. When false, private values will be 86 // skipped. 87 bool skip_private_vars; 88 89 // When set, values copied to the destination scope will be marked as used 90 // so won't trigger an unused variable warning. You want this when doing an 91 // import, for example, or files that don't need a variable from the .gni 92 // file will throw an error. 93 bool mark_dest_used; 94 95 // When set, those variables are not merged. 96 std::set<std::string> excluded_values; 97 }; 98 99 // Details about a Scope's creation as a template invocation 100 struct TemplateInvocationEntry { 101 // Produce a printable string that describes the template invocation: 102 // 103 // 'template_name("target_name") //some/BUILD.gn:<line>' 104 // 105 // The target name is only the string that's passed to the template as the 106 // name, it's not a complete GN label. 107 std::string Describe() const; 108 109 std::string template_name; 110 std::string target_name; 111 Location location; 112 }; 113 114 // Creates an empty toplevel scope. 115 explicit Scope(const Settings* settings); 116 117 // Creates a dependent scope. 118 explicit Scope(Scope* parent); 119 explicit Scope(const Scope* parent); 120 121 ~Scope(); 122 settings()123 const Settings* settings() const { return settings_; } 124 125 // See the const_/mutable_containing_ var declarations below. Yes, it's a 126 // bit weird that we can have a const pointer to the "mutable" one. mutable_containing()127 Scope* mutable_containing() { return mutable_containing_; } mutable_containing()128 const Scope* mutable_containing() const { return mutable_containing_; } const_containing()129 const Scope* const_containing() const { return const_containing_; } containing()130 const Scope* containing() const { 131 return mutable_containing_ ? mutable_containing_ : const_containing_; 132 } 133 134 // Clears any references to containing scopes. This scope will now be 135 // self-sufficient. 136 void DetachFromContaining(); 137 138 // Returns true if the scope has any values set. This does not check other 139 // things that may be set like templates or defaults. 140 // 141 // Currently this does not search nested scopes and this will assert if you 142 // want to search nested scopes. The enum is passed so the callers are 143 // unambiguous about nested scope handling. This can be added if needed. 144 bool HasValues(SearchNested search_nested) const; 145 146 // Returns NULL if there's no such value. 147 // 148 // counts_as_used should be set if the variable is being read in a way that 149 // should count for unused variable checking. 150 // 151 // found_in_scope is set to the scope that contains the definition of the 152 // ident. If the value was provided programmatically (like host_cpu), 153 // found_in_scope will be set to null. 154 const Value* GetValue(std::string_view ident, bool counts_as_used); 155 const Value* GetValue(std::string_view ident) const; 156 const Value* GetValueWithScope(std::string_view ident, 157 const Scope** found_in_scope) const; 158 const Value* GetValueWithScope(std::string_view ident, 159 bool counts_as_used, 160 const Scope** found_in_scope); 161 162 // Returns the requested value as a mutable one if possible. If the value 163 // is not found in a mutable scope, then returns null. Note that the value 164 // could still exist in a const scope, so GetValue() could still return 165 // non-null in this case. 166 // 167 // Say you have a local scope that then refers to the const root scope from 168 // the master build config. You can't change the values from the master 169 // build config (it's read-only so it can be read from multiple threads 170 // without locking). Read-only operations would work on values from the root 171 // scope, but write operations would only work on values in the derived 172 // scope(s). 173 // 174 // Be careful when calling this. It's not normally correct to modify values, 175 // but you should instead do a new Set each time. 176 // 177 // Consider this code: 178 // a = 5 179 // { 180 // a = 6 181 // } 182 // The 6 should get set on the nested scope rather than modify the value 183 // in the outer one. 184 Value* GetMutableValue(std::string_view ident, 185 SearchNested search_mode, 186 bool counts_as_used); 187 188 // Returns the std::string_view used to identify the value. This string piece 189 // will have the same contents as "ident" passed in, but may point to a 190 // different underlying buffer. This is useful because this std::string_view 191 // is static and won't be deleted for the life of the program, so it can be 192 // used as keys in places that may outlive a temporary. It will return an 193 // empty string for programmatic and nonexistent values. 194 std::string_view GetStorageKey(std::string_view ident) const; 195 196 // The set_node indicates the statement that caused the set, for displaying 197 // errors later. Returns a pointer to the value in the current scope (a copy 198 // is made for storage). 199 Value* SetValue(std::string_view ident, Value v, const ParseNode* set_node); 200 201 // Removes the value with the given identifier if it exists on the current 202 // scope. This does not search recursive scopes. Does nothing if not found. 203 void RemoveIdentifier(std::string_view ident); 204 205 // Removes from this scope all identifiers and templates that are considered 206 // private. 207 void RemovePrivateIdentifiers(); 208 209 // Templates associated with this scope. A template can only be set once, so 210 // AddTemplate will fail and return false if a rule with that name already 211 // exists. GetTemplate returns NULL if the rule doesn't exist, and it will 212 // check all containing scoped rescursively. 213 bool AddTemplate(const std::string& name, const Template* templ); 214 const Template* GetTemplate(const std::string& name) const; 215 216 // Marks the given identifier as (un)used in the current scope. 217 void MarkUsed(std::string_view ident); 218 void MarkAllUsed(); 219 void MarkAllUsed(const std::set<std::string>& excluded_values); 220 void MarkUnused(std::string_view ident); 221 222 // Checks to see if the scope has a var set that hasn't been used. This is 223 // called before replacing the var with a different one. It does not check 224 // containing scopes. 225 // 226 // If the identifier is present but hasnn't been used, return true. 227 bool IsSetButUnused(std::string_view ident) const; 228 229 // Checks the scope to see if any values were set but not used, and fills in 230 // the error and returns false if they were. 231 bool CheckForUnusedVars(Err* err) const; 232 233 // Returns all values set in the current scope, without going to the parent 234 // scopes. 235 void GetCurrentScopeValues(KeyValueMap* output) const; 236 237 // Returns true if the values in the current scope are the same as all 238 // values in the given scope, without going to the parent scopes. Returns 239 // false if not. 240 bool CheckCurrentScopeValuesEqual(const Scope* other) const; 241 242 // Copies this scope's values into the destination. Values from the 243 // containing scope(s) (normally shadowed into the current one) will not be 244 // copied, neither will the reference to the containing scope (this is why 245 // it's "non-recursive"). 246 // 247 // This is used in different contexts. When generating the error, the given 248 // parse node will be blamed, and the given desc will be used to describe 249 // the operation that doesn't support doing this. For example, desc_for_err 250 // would be "import" when doing an import, and the error string would say 251 // something like "The import contains...". 252 bool NonRecursiveMergeTo(Scope* dest, 253 const MergeOptions& options, 254 const ParseNode* node_for_err, 255 const char* desc_for_err, 256 Err* err) const; 257 258 // Constructs a scope that is a copy of the current one. Nested scopes will 259 // be collapsed until we reach a const containing scope. Private values will 260 // be included. The resulting closure will reference the const containing 261 // scope as its containing scope (since we assume the const scope won't 262 // change, we don't have to copy its values). 263 std::unique_ptr<Scope> MakeClosure() const; 264 265 // Makes an empty scope with the given name. Overwrites any existing one. 266 Scope* MakeTargetDefaults(const std::string& target_type); 267 268 // Gets the scope associated with the given target name, or null if it hasn't 269 // been set. 270 const Scope* GetTargetDefaults(const std::string& target_type) const; 271 272 // Indicates if we're currently processing the build configuration file. 273 // This is true when processing the config file for any toolchain. 274 // 275 // To set or clear the flag, it must currently be in the opposite state in 276 // the current scope. Note that querying the state of the flag recursively 277 // checks all containing scopes until it reaches the top or finds the flag 278 // set. 279 void SetProcessingBuildConfig(); 280 void ClearProcessingBuildConfig(); 281 bool IsProcessingBuildConfig() const; 282 283 // Indicates if we're currently processing an import file. 284 // 285 // See SetProcessingBaseConfig for how flags work. 286 void SetProcessingImport(); 287 void ClearProcessingImport(); 288 bool IsProcessingImport() const; 289 290 // The source directory associated with this scope. This will check embedded 291 // scopes until it finds a nonempty source directory. This will default to 292 // an empty dir if no containing scope has a source dir set. 293 const SourceDir& GetSourceDir() const; set_source_dir(const SourceDir & d)294 void set_source_dir(const SourceDir& d) { source_dir_ = d; } 295 296 // Set of files that may affect the execution of this scope. Note that this 297 // set is constructed conservatively, meaning that every file that can 298 // potentially affect this scope is included, but not necessarily every change 299 // to these files will affect this scope. build_dependency_files()300 const SourceFileSet& build_dependency_files() const { 301 return build_dependency_files_; 302 } 303 void AddBuildDependencyFile(const SourceFile& build_dependency_file); 304 void AddBuildDependencyFiles(const SourceFileSet& build_dependency_files); 305 306 // The item collector is where Items (Targets, Configs, etc.) go that have 307 // been defined. If a scope can generate items, this non-owning pointer will 308 // point to the storage for such items. The creator of this scope will be 309 // responsible for setting up the collector and then dealing with the 310 // collected items once execution of the context is complete. 311 // 312 // The items in a scope are collected as we go and then dispatched at the end 313 // of execution of a scope so that we can query the previously-generated 314 // targets (like getting the outputs). 315 // 316 // This can be null if the current scope can not generate items (like for 317 // imports and such). 318 // 319 // When retrieving the collector, the non-const scopes are recursively 320 // queried. The collector is not copied for closures, etc. set_item_collector(ItemVector * collector)321 void set_item_collector(ItemVector* collector) { 322 item_collector_ = collector; 323 } 324 ItemVector* GetItemCollector(); 325 326 // Properties are opaque pointers that code can use to set state on a Scope 327 // that it can retrieve later. 328 // 329 // The key should be a pointer to some use-case-specific object (to avoid 330 // collisions, otherwise it doesn't matter). Memory management is up to the 331 // setter. Setting the value to NULL will delete the property. 332 // 333 // Getting a property recursively searches all scopes, and the optional 334 // |found_on_scope| variable will be filled with the actual scope containing 335 // the key (if the pointer is non-NULL). 336 void SetProperty(const void* key, void* value); 337 void* GetProperty(const void* key, const Scope** found_on_scope) const; 338 339 // Track template invocations for printing or debugging. 340 void SetTemplateInvocationEntry(std::string template_name, 341 std::string target_name, 342 Location location); 343 344 // Return a vector containing the current stack of template invocations that 345 // lead up to this scope. 346 std::vector<TemplateInvocationEntry> GetTemplateInvocationEntries() const; 347 348 private: 349 friend class ProgrammaticProvider; 350 351 struct Record { RecordRecord352 Record() : used(false) {} RecordRecord353 explicit Record(const Value& v) : used(false), value(v) {} 354 355 bool used; // Set to true when the variable is used. 356 Value value; 357 }; 358 359 using RecordMap = std::unordered_map<std::string_view, Record>; 360 361 void AddProvider(ProgrammaticProvider* p); 362 void RemoveProvider(ProgrammaticProvider* p); 363 364 // Returns true if the two RecordMaps contain the same values (the origins 365 // of the values may be different). 366 static bool RecordMapValuesEqual(const RecordMap& a, const RecordMap& b); 367 368 // Walk up the containing scopes and any "invoker" Value scopes to gather any 369 // previous template invocations. 370 void AppendTemplateInvocationEntries( 371 std::vector<TemplateInvocationEntry>* out) const; 372 373 // Walk up the containing scopes to find a TemplateInvocationEntry. 374 const TemplateInvocationEntry* FindTemplateInvocationEntry() const; 375 376 // Scopes can have no containing scope (both null), a mutable containing 377 // scope, or a const containing scope. The reason is that when we're doing 378 // a new target, we want to refer to the base_config scope which will be read 379 // by multiple threads at the same time, so we REALLY want it to be const. 380 // When you just do a nested {}, however, we sometimes want to be able to 381 // change things (especially marking unused vars). 382 const Scope* const_containing_; 383 Scope* mutable_containing_; 384 385 const Settings* settings_; 386 387 // Bits set for different modes. See the flag definitions in the .cc file 388 // for more. 389 unsigned mode_flags_; 390 391 RecordMap values_; 392 393 // If this is a template scope, track the template invocation. 394 std::unique_ptr<TemplateInvocationEntry> template_invocation_entry_; 395 396 // Note that this can't use string pieces since the names are constructed from 397 // Values which might be deallocated before this goes out of scope. 398 using NamedScopeMap = std::unordered_map<std::string, std::unique_ptr<Scope>>; 399 NamedScopeMap target_defaults_; 400 401 // Owning pointers, must be deleted. 402 using TemplateMap = std::map<std::string, scoped_refptr<const Template>>; 403 TemplateMap templates_; 404 405 ItemVector* item_collector_; 406 407 // Opaque pointers. See SetProperty() above. 408 using PropertyMap = std::map<const void*, void*>; 409 PropertyMap properties_; 410 411 using ProviderSet = std::set<ProgrammaticProvider*>; 412 ProviderSet programmatic_providers_; 413 414 SourceDir source_dir_; 415 416 SourceFileSet build_dependency_files_; 417 418 Scope(const Scope&) = delete; 419 Scope& operator=(const Scope&) = delete; 420 }; 421 422 #endif // TOOLS_GN_SCOPE_H_ 423