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