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