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 #include "gn/functions.h"
6
7 #include <stddef.h>
8 #include <cctype>
9 #include <memory>
10 #include <utility>
11
12 #include "base/environment.h"
13 #include "base/strings/string_util.h"
14 #include "gn/build_settings.h"
15 #include "gn/config.h"
16 #include "gn/config_values_generator.h"
17 #include "gn/err.h"
18 #include "gn/input_file.h"
19 #include "gn/ohos_components_checker.h"
20 #include "gn/ohos_components_mapping.h"
21 #include "gn/parse_node_value_adapter.h"
22 #include "gn/parse_tree.h"
23 #include "gn/pool.h"
24 #include "gn/scheduler.h"
25 #include "gn/scope.h"
26 #include "gn/settings.h"
27 #include "gn/template.h"
28 #include "gn/token.h"
29 #include "gn/value.h"
30 #include "gn/value_extractors.h"
31 #include "gn/variables.h"
32
33 namespace {
34
35 // Some functions take a {} following them, and some don't. For the ones that
36 // don't, this is used to verify that the given block node is null and will
37 // set the error accordingly if it's not. Returns true if the block is null.
VerifyNoBlockForFunctionCall(const FunctionCallNode * function,const BlockNode * block,Err * err)38 bool VerifyNoBlockForFunctionCall(const FunctionCallNode* function,
39 const BlockNode* block,
40 Err* err) {
41 if (!block)
42 return true;
43
44 *err =
45 Err(block, "Unexpected '{'.",
46 "This function call doesn't take a {} block following it, and you\n"
47 "can't have a {} block that's not connected to something like an if\n"
48 "statement or a target declaration.");
49 err->AppendRange(function->function().range());
50 return false;
51 }
52
53 // This key is set as a scope property on the scope of a declare_args() block,
54 // in order to prevent reading a variable defined earlier in the same call
55 // (see `gn help declare_args` for more).
56 const void* kInDeclareArgsKey = nullptr;
57
58 } // namespace
59
EnsureNotReadingFromSameDeclareArgs(const ParseNode * node,const Scope * cur_scope,const Scope * val_scope,Err * err)60 bool EnsureNotReadingFromSameDeclareArgs(const ParseNode* node,
61 const Scope* cur_scope,
62 const Scope* val_scope,
63 Err* err) {
64 // If the value didn't come from a scope at all, we're safe.
65 if (!val_scope)
66 return true;
67
68 const Scope* val_args_scope = nullptr;
69 val_scope->GetProperty(&kInDeclareArgsKey, &val_args_scope);
70
71 const Scope* cur_args_scope = nullptr;
72 cur_scope->GetProperty(&kInDeclareArgsKey, &cur_args_scope);
73 if (!val_args_scope || !cur_args_scope || (val_args_scope != cur_args_scope))
74 return true;
75
76 *err =
77 Err(node,
78 "Reading a variable defined in the same declare_args() call.\n"
79 "\n"
80 "If you need to set the value of one arg based on another, put\n"
81 "them in two separate declare_args() calls, one after the other.\n");
82 return false;
83 }
84
EnsureNotProcessingImport(const ParseNode * node,const Scope * scope,Err * err)85 bool EnsureNotProcessingImport(const ParseNode* node,
86 const Scope* scope,
87 Err* err) {
88 if (scope->IsProcessingImport()) {
89 *err =
90 Err(node, "Not valid from an import.",
91 "Imports are for defining defaults, variables, and rules. The\n"
92 "appropriate place for this kind of thing is really in a normal\n"
93 "BUILD file.");
94 return false;
95 }
96 return true;
97 }
98
EnsureNotProcessingBuildConfig(const ParseNode * node,const Scope * scope,Err * err)99 bool EnsureNotProcessingBuildConfig(const ParseNode* node,
100 const Scope* scope,
101 Err* err) {
102 if (scope->IsProcessingBuildConfig()) {
103 *err = Err(node, "Not valid from the build config.",
104 "You can't do this kind of thing from the build config script, "
105 "silly!\nPut it in a regular BUILD file.");
106 return false;
107 }
108 return true;
109 }
110
FillTargetBlockScope(const Scope * scope,const FunctionCallNode * function,const std::string & target_type,const BlockNode * block,const std::vector<Value> & args,Scope * block_scope,Err * err)111 bool FillTargetBlockScope(const Scope* scope,
112 const FunctionCallNode* function,
113 const std::string& target_type,
114 const BlockNode* block,
115 const std::vector<Value>& args,
116 Scope* block_scope,
117 Err* err) {
118 if (!block) {
119 FillNeedsBlockError(function, err);
120 return false;
121 }
122
123 // Copy the target defaults, if any, into the scope we're going to execute
124 // the block in.
125 const Scope* default_scope = scope->GetTargetDefaults(target_type);
126 if (default_scope) {
127 Scope::MergeOptions merge_options;
128 merge_options.skip_private_vars = true;
129 if (!default_scope->NonRecursiveMergeTo(block_scope, merge_options,
130 function, "target defaults", err))
131 return false;
132 }
133
134 // The name is the single argument to the target function.
135 if (!EnsureSingleStringArg(function, args, err))
136 return false;
137
138 // Set the target name variable to the current target, and mark it used
139 // because we don't want to issue an error if the script ignores it.
140 const std::string_view target_name(variables::kTargetName);
141 block_scope->SetValue(target_name, Value(function, args[0].string_value()),
142 function);
143 block_scope->MarkUsed(target_name);
144 return true;
145 }
146
FillNeedsBlockError(const FunctionCallNode * function,Err * err)147 void FillNeedsBlockError(const FunctionCallNode* function, Err* err) {
148 *err = Err(function->function(), "This function call requires a block.",
149 "The block's \"{\" must be on the same line as the function "
150 "call's \")\".");
151 }
152
EnsureSingleStringArg(const FunctionCallNode * function,const std::vector<Value> & args,Err * err)153 bool EnsureSingleStringArg(const FunctionCallNode* function,
154 const std::vector<Value>& args,
155 Err* err) {
156 if (args.size() != 1) {
157 *err = Err(function->function(), "Incorrect arguments.",
158 "This function requires a single string argument.");
159 return false;
160 }
161 return args[0].VerifyTypeIs(Value::STRING, err);
162 }
163
ToolchainLabelForScope(const Scope * scope)164 const Label& ToolchainLabelForScope(const Scope* scope) {
165 return scope->settings()->toolchain_label();
166 }
167
MakeLabelForScope(const Scope * scope,const FunctionCallNode * function,const std::string & name)168 Label MakeLabelForScope(const Scope* scope,
169 const FunctionCallNode* function,
170 const std::string& name) {
171 const Label& toolchain_label = ToolchainLabelForScope(scope);
172 return Label(scope->GetSourceDir(), name, toolchain_label.dir(),
173 toolchain_label.name());
174 }
175
176 // static
177 const int NonNestableBlock::kKey = 0;
178
NonNestableBlock(Scope * scope,const FunctionCallNode * function,const char * type_description)179 NonNestableBlock::NonNestableBlock(Scope* scope,
180 const FunctionCallNode* function,
181 const char* type_description)
182 : scope_(scope),
183 function_(function),
184 type_description_(type_description),
185 key_added_(false) {}
186
~NonNestableBlock()187 NonNestableBlock::~NonNestableBlock() {
188 if (key_added_)
189 scope_->SetProperty(&kKey, nullptr);
190 }
191
Enter(Err * err)192 bool NonNestableBlock::Enter(Err* err) {
193 void* scope_value = scope_->GetProperty(&kKey, nullptr);
194 if (scope_value) {
195 // Existing block.
196 const NonNestableBlock* existing =
197 reinterpret_cast<const NonNestableBlock*>(scope_value);
198 *err = Err(function_, "Can't nest these things.",
199 std::string("You are trying to nest a ") + type_description_ +
200 " inside a " + existing->type_description_ + ".");
201 err->AppendSubErr(Err(existing->function_, "The enclosing block."));
202 return false;
203 }
204
205 scope_->SetProperty(&kKey, this);
206 key_added_ = true;
207 return true;
208 }
209
210 namespace functions {
211
212 // assert ----------------------------------------------------------------------
213
214 const char kAssert[] = "assert";
215 const char kAssert_HelpShort[] =
216 "assert: Assert an expression is true at generation time.";
217 const char kAssert_Help[] =
218 R"(assert: Assert an expression is true at generation time.
219
220 assert(<condition> [, <error string>])
221
222 If the condition is false, the build will fail with an error. If the
223 optional second argument is provided, that string will be printed
224 with the error message.
225
226 Examples
227
228 assert(is_win)
229 assert(defined(sources), "Sources must be defined");
230 )";
231
RunAssert(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)232 Value RunAssert(Scope* scope,
233 const FunctionCallNode* function,
234 const std::vector<Value>& args,
235 Err* err) {
236 // Check usage: Assert takes 1 or 2 arguments.
237 if (args.size() != 1 && args.size() != 2) {
238 *err = Err(function->function(), "Wrong number of arguments.",
239 "assert() takes one or two arguments, "
240 "were you expecting something else?");
241 return Value();
242 }
243
244 // Check usage: The first argument must be a boolean.
245 if (args[0].type() != Value::BOOLEAN) {
246 *err = Err(function->function(), "Assertion value not a bool.");
247 return Value();
248 }
249 bool assertion_passed = args[0].boolean_value();
250
251 // Check usage: The second argument, if present, must be a string.
252 if (args.size() == 2 && args[1].type() != Value::STRING) {
253 *err = Err(function->function(), "Assertion message is not a string.");
254 return Value();
255 }
256
257 // Assertion passed: there is nothing to do, so return an empty value.
258 if (assertion_passed) {
259 return Value();
260 }
261
262 // Assertion failed; try to make a useful message and report it.
263 if (args.size() == 2) {
264 *err =
265 Err(function->function(), "Assertion failed.", args[1].string_value());
266 } else {
267 *err = Err(function->function(), "Assertion failed.");
268 }
269 if (args[0].origin()) {
270 // If you do "assert(foo)" we'd ideally like to show you where foo was
271 // set, and in this case the origin of the args will tell us that.
272 // However, if you do "assert(foo && bar)" the source of the value will
273 // be the assert like, which isn't so helpful.
274 //
275 // So we try to see if the args are from the same line or not. This will
276 // break if you do "assert(\nfoo && bar)" and we may show the second line
277 // as the source, oh well. The way around this is to check to see if the
278 // origin node is inside our function call block.
279 Location origin_location = args[0].origin()->GetRange().begin();
280 if (origin_location.file() != function->function().location().file() ||
281 origin_location.line_number() !=
282 function->function().location().line_number()) {
283 err->AppendSubErr(
284 Err(args[0].origin()->GetRange(), "", "This is where it was set."));
285 }
286 }
287 return Value();
288 }
289
290 // config ----------------------------------------------------------------------
291
292 const char kConfig[] = "config";
293 const char kConfig_HelpShort[] = "config: Defines a configuration object.";
294 const char kConfig_Help[] =
295 R"(config: Defines a configuration object.
296
297 Configuration objects can be applied to targets and specify sets of compiler
298 flags, includes, defines, etc. They provide a way to conveniently group sets
299 of this configuration information.
300
301 A config is referenced by its label just like a target.
302
303 The values in a config are additive only. If you want to remove a flag you
304 need to remove the corresponding config that sets it. The final set of flags,
305 defines, etc. for a target is generated in this order:
306
307 1. The values specified directly on the target (rather than using a config).
308 2. The configs specified in the target's "configs" list, in order.
309 3. Public_configs from a breadth-first traversal of the dependency tree in
310 the order that the targets appear in "deps".
311 4. All dependent configs from a breadth-first traversal of the dependency
312 tree in the order that the targets appear in "deps".
313
314 More background
315
316 Configs solve a problem where the build system needs to have a higher-level
317 understanding of various compiler settings. For example, some compiler flags
318 have to appear in a certain order relative to each other, some settings like
319 defines and flags logically go together, and the build system needs to
320 de-duplicate flags even though raw command-line parameters can't always be
321 operated on in that way.
322
323 The config gives a name to a group of settings that can then be reasoned
324 about by GN. GN can know that configs with the same label are the same thing
325 so can be de-duplicated. It allows related settings to be grouped so they
326 are added or removed as a unit. And it allows targets to refer to settings
327 with conceptual names ("no_rtti", "enable_exceptions", etc.) rather than
328 having to hard-coding every compiler's flags each time they are referred to.
329
330 Variables valid in a config definition
331
332 )"
333
334 CONFIG_VALUES_VARS_HELP
335
336 R"( Nested configs: configs
337 General: visibility
338
339 Variables on a target used to apply configs
340
341 all_dependent_configs, configs, public_configs
342
343 Example
344
345 config("myconfig") {
346 include_dirs = [ "include/common" ]
347 defines = [ "ENABLE_DOOM_MELON" ]
348 }
349
350 executable("mything") {
351 configs = [ ":myconfig" ]
352 }
353 )";
354
RunConfig(const FunctionCallNode * function,const std::vector<Value> & args,Scope * scope,Err * err)355 Value RunConfig(const FunctionCallNode* function,
356 const std::vector<Value>& args,
357 Scope* scope,
358 Err* err) {
359 NonNestableBlock non_nestable(scope, function, "config");
360 if (!non_nestable.Enter(err))
361 return Value();
362
363 if (!EnsureSingleStringArg(function, args, err) ||
364 !EnsureNotProcessingImport(function, scope, err))
365 return Value();
366
367 Label label(MakeLabelForScope(scope, function, args[0].string_value()));
368
369 if (g_scheduler->verbose_logging())
370 g_scheduler->Log("Defining config", label.GetUserVisibleName(true));
371
372 // Create the new config.
373 std::unique_ptr<Config> config = std::make_unique<Config>(
374 scope->settings(), label, scope->build_dependency_files());
375 config->set_defined_from(function);
376 if (!Visibility::FillItemVisibility(config.get(), scope, err))
377 return Value();
378
379 // Fill the flags and such.
380 const SourceDir& input_dir = scope->GetSourceDir();
381 ConfigValuesGenerator gen(&config->own_values(), scope, input_dir, err);
382 gen.Run();
383 if (err->has_error())
384 return Value();
385
386 // Read sub-configs.
387 const Value* configs_value = scope->GetValue(variables::kConfigs, true);
388 if (configs_value) {
389 ExtractListOfUniqueLabels(scope->settings()->build_settings(),
390 *configs_value, scope->GetSourceDir(),
391 ToolchainLabelForScope(scope), &config->configs(),
392 err);
393 }
394 if (err->has_error())
395 return Value();
396
397 // Save the generated item.
398 Scope::ItemVector* collector = scope->GetItemCollector();
399 if (!collector) {
400 *err = Err(function, "Can't define a config in this context.");
401 return Value();
402 }
403 collector->push_back(std::move(config));
404
405 return Value();
406 }
407
408 // declare_args ----------------------------------------------------------------
409
410 const char kDeclareArgs[] = "declare_args";
411 const char kDeclareArgs_HelpShort[] = "declare_args: Declare build arguments.";
412 const char kDeclareArgs_Help[] =
413 R"(declare_args: Declare build arguments.
414
415 Introduces the given arguments into the current scope. If they are not
416 specified on the command line or in a toolchain's arguments, the default
417 values given in the declare_args block will be used. However, these defaults
418 will not override command-line values.
419
420 See also "gn help buildargs" for an overview.
421
422 The precise behavior of declare args is:
423
424 1. The declare_args() block executes. Any variable defined in the enclosing
425 scope is available for reading, but any variable defined earlier in
426 the current scope is not (since the overrides haven't been applied yet).
427
428 2. At the end of executing the block, any variables set within that scope
429 are saved, with the values specified in the block used as the "default value"
430 for that argument. Once saved, these variables are available for override
431 via args.gn.
432
433 3. User-defined overrides are applied. Anything set in "gn args" now
434 overrides any default values. The resulting set of variables is promoted
435 to be readable from the following code in the file.
436
437 This has some ramifications that may not be obvious:
438
439 - You should not perform difficult work inside a declare_args block since
440 this only sets a default value that may be discarded. In particular,
441 don't use the result of exec_script() to set the default value. If you
442 want to have a script-defined default, set some default "undefined" value
443 like [], "", or -1, and after the declare_args block, call exec_script if
444 the value is unset by the user.
445
446 - Because you cannot read the value of a variable defined in the same
447 block, if you need to make the default value of one arg depend
448 on the possibly-overridden value of another, write two separate
449 declare_args() blocks:
450
451 declare_args() {
452 enable_foo = true
453 }
454 declare_args() {
455 # Bar defaults to same user-overridden state as foo.
456 enable_bar = enable_foo
457 }
458
459 Example
460
461 declare_args() {
462 enable_teleporter = true
463 enable_doom_melon = false
464 }
465
466 If you want to override the (default disabled) Doom Melon:
467 gn --args="enable_doom_melon=true enable_teleporter=true"
468 This also sets the teleporter, but it's already defaulted to on so it will
469 have no effect.
470 )";
471
RunDeclareArgs(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,BlockNode * block,Err * err)472 Value RunDeclareArgs(Scope* scope,
473 const FunctionCallNode* function,
474 const std::vector<Value>& args,
475 BlockNode* block,
476 Err* err) {
477 NonNestableBlock non_nestable(scope, function, "declare_args");
478 if (!non_nestable.Enter(err))
479 return Value();
480
481 Scope block_scope(scope);
482 block_scope.SetProperty(&kInDeclareArgsKey, &block_scope);
483 block->Execute(&block_scope, err);
484 if (err->has_error())
485 return Value();
486
487 // Pass the values from our scope into the Args object for adding to the
488 // scope with the proper values (taking into account the defaults given in
489 // the block_scope, and arguments passed into the build).
490 Scope::KeyValueMap values;
491 block_scope.GetCurrentScopeValues(&values);
492 scope->settings()->build_settings()->build_args().DeclareArgs(values, scope,
493 err);
494 return Value();
495 }
496
497 // defined ---------------------------------------------------------------------
498
499 const char kDefined[] = "defined";
500 const char kDefined_HelpShort[] =
501 "defined: Returns whether an identifier is defined.";
502 const char kDefined_Help[] =
503 R"(defined: Returns whether an identifier is defined.
504
505 Returns true if the given argument is defined. This is most useful in
506 templates to assert that the caller set things up properly.
507
508 You can pass an identifier:
509 defined(foo)
510 which will return true or false depending on whether foo is defined in the
511 current scope.
512
513 You can also check a named scope:
514 defined(foo.bar)
515 which will return true or false depending on whether bar is defined in the
516 named scope foo. It will throw an error if foo is not defined or is not a
517 scope.
518
519 You can also check a named scope using a subscript string expression:
520 defined(foo[bar + "_name"])
521 which will return true or false depending on whether the subscript
522 expression expands to the name of a member of the scope foo. It will
523 throw an error if foo is not defined or is not a scope, or if the
524 expression does not expand to a string, or if it is an empty string.
525
526 Example
527
528 template("mytemplate") {
529 # To help users call this template properly...
530 assert(defined(invoker.sources), "Sources must be defined")
531
532 # If we want to accept an optional "values" argument, we don't
533 # want to dereference something that may not be defined.
534 if (defined(invoker.values)) {
535 values = invoker.values
536 } else {
537 values = "some default value"
538 }
539 }
540 )";
541
RunDefined(Scope * scope,const FunctionCallNode * function,const ListNode * args_list,Err * err)542 Value RunDefined(Scope* scope,
543 const FunctionCallNode* function,
544 const ListNode* args_list,
545 Err* err) {
546 const auto& args_vector = args_list->contents();
547 if (args_vector.size() != 1) {
548 *err = Err(function, "Wrong number of arguments to defined().",
549 "Expecting exactly one.");
550 return Value();
551 }
552
553 const IdentifierNode* identifier = args_vector[0]->AsIdentifier();
554 if (identifier) {
555 // Passed an identifier "defined(foo)".
556 if (scope->GetValue(identifier->value().value()))
557 return Value(function, true);
558 return Value(function, false);
559 }
560
561 const AccessorNode* accessor = args_vector[0]->AsAccessor();
562 if (accessor) {
563 // The base of the accessor must be a scope if it's defined.
564 const Value* base = scope->GetValue(accessor->base().value());
565 if (!base) {
566 *err = Err(accessor, "Undefined identifier");
567 return Value();
568 }
569 if (!base->VerifyTypeIs(Value::SCOPE, err))
570 return Value();
571
572 std::string scope_member;
573
574 if (accessor->member()) {
575 // Passed an accessor "defined(foo.bar)".
576 scope_member = accessor->member()->value().value();
577 } else if (accessor->subscript()) {
578 // Passed an accessor "defined(foo["bar"])".
579 Value subscript_value = accessor->subscript()->Execute(scope, err);
580 if (err->has_error())
581 return Value();
582 if (!subscript_value.VerifyTypeIs(Value::STRING, err))
583 return Value();
584 scope_member = subscript_value.string_value();
585 }
586 if (!scope_member.empty()) {
587 // Check the member inside the scope to see if its defined.
588 bool result = base->scope_value()->GetValue(scope_member) != nullptr;
589 return Value(function, result);
590 }
591 }
592
593 // Argument is invalid.
594 *err = Err(function, "Bad thing passed to defined().",
595 "It should be of the form defined(foo), defined(foo.bar) or "
596 "defined(foo[<string-expression>]).");
597 return Value();
598 }
599
600 // getenv ----------------------------------------------------------------------
601
602 const char kGetEnv[] = "getenv";
603 const char kGetEnv_HelpShort[] = "getenv: Get an environment variable.";
604 const char kGetEnv_Help[] =
605 R"(getenv: Get an environment variable.
606
607 value = getenv(env_var_name)
608
609 Returns the value of the given environment variable. If the value is not
610 found, it will try to look up the variable with the "opposite" case (based on
611 the case of the first letter of the variable), but is otherwise
612 case-sensitive.
613
614 If the environment variable is not found, the empty string will be returned.
615 Note: it might be nice to extend this if we had the concept of "none" in the
616 language to indicate lookup failure.
617
618 Example
619
620 home_dir = getenv("HOME")
621 )";
622
RunGetEnv(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)623 Value RunGetEnv(Scope* scope,
624 const FunctionCallNode* function,
625 const std::vector<Value>& args,
626 Err* err) {
627 if (!EnsureSingleStringArg(function, args, err))
628 return Value();
629
630 std::unique_ptr<base::Environment> env(base::Environment::Create());
631
632 std::string result;
633 if (!env->GetVar(args[0].string_value().c_str(), &result))
634 return Value(function, ""); // Not found, return empty string.
635 return Value(function, result);
636 }
637
638 // import ----------------------------------------------------------------------
639
640 const char kImport[] = "import";
641 const char kImport_HelpShort[] =
642 "import: Import a file into the current scope.";
643 const char kImport_Help[] =
644 R"(import: Import a file into the current scope.
645
646 The import command loads the rules and variables resulting from executing the
647 given file into the current scope.
648
649 By convention, imported files are named with a .gni extension.
650
651 An import is different than a C++ "include". The imported file is executed in
652 a standalone environment from the caller of the import command. The results
653 of this execution are cached for other files that import the same .gni file.
654
655 Note that you can not import a BUILD.gn file that's otherwise used in the
656 build. Files must either be imported or implicitly loaded as a result of deps
657 rules, but not both.
658
659 The imported file's scope will be merged with the scope at the point import
660 was called. If there is a conflict (both the current scope and the imported
661 file define some variable or rule with the same name but different value), a
662 runtime error will be thrown. Therefore, it's good practice to minimize the
663 stuff that an imported file defines.
664
665 Variables and templates beginning with an underscore '_' are considered
666 private and will not be imported. Imported files can use such variables for
667 internal computation without affecting other files.
668
669 Examples
670
671 import("//build/rules/idl_compilation_rule.gni")
672
673 # Looks in the current directory.
674 import("my_vars.gni")
675 )";
676
RunImport(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)677 Value RunImport(Scope* scope,
678 const FunctionCallNode* function,
679 const std::vector<Value>& args,
680 Err* err) {
681 if (!EnsureSingleStringArg(function, args, err))
682 return Value();
683
684 const SourceDir& input_dir = scope->GetSourceDir();
685 SourceFile import_file = input_dir.ResolveRelativeFile(
686 args[0], err, scope->settings()->build_settings()->root_path_utf8());
687
688 const OhosComponentChecker *checker = OhosComponentChecker::getInstance();
689 if (checker != nullptr) {
690 checker->CheckImportOther(function, scope->settings()->build_settings(),
691 input_dir.value(), import_file.value(), err);
692 }
693
694 std::string mapping_file = "";
695 const OhosComponentMapping *mapping = OhosComponentMapping::getInstance();
696 if (mapping != nullptr) {
697 mapping_file = mapping->MappingImportOther(scope->settings()->build_settings(),
698 input_dir.value(), import_file.value());
699 }
700
701 if (mapping_file != "") {
702 SourceFile real_file(mapping_file);
703 scope->AddBuildDependencyFile(real_file);
704 if (!err->has_error()) {
705 scope->settings()->import_manager().DoImport(real_file, function, scope, err);
706 }
707 return Value();
708 }
709 scope->AddBuildDependencyFile(import_file);
710 if (!err->has_error()) {
711 scope->settings()->import_manager().DoImport(import_file, function, scope,
712 err);
713 }
714 return Value();
715 }
716
717 // not_needed -----------------------------------------------------------------
718
719 const char kNotNeeded[] = "not_needed";
720 const char kNotNeeded_HelpShort[] =
721 "not_needed: Mark variables from scope as not needed.";
722 const char kNotNeeded_Help[] =
723 R"(not_needed: Mark variables from scope as not needed.
724
725 not_needed(variable_list_or_star, variable_to_ignore_list = [])
726 not_needed(from_scope, variable_list_or_star,
727 variable_to_ignore_list = [])
728
729 Mark the variables in the current or given scope as not needed, which means
730 you will not get an error about unused variables for these. The
731 variable_to_ignore_list allows excluding variables from "all matches" if
732 variable_list_or_star is "*".
733
734 Example
735
736 not_needed("*", [ "config" ])
737 not_needed([ "data_deps", "deps" ])
738 not_needed(invoker, "*", [ "config" ])
739 not_needed(invoker, [ "data_deps", "deps" ])
740 )";
741
742 Value RunNotNeeded(Scope* scope,
743 const FunctionCallNode* function,
744 const ListNode* args_list,
745 Err* err) {
746 const auto& args_vector = args_list->contents();
747 if (args_vector.size() < 1 || args_vector.size() > 3) {
748 *err = Err(function, "Wrong number of arguments.",
749 "Expecting one, two or three arguments.");
750 return Value();
751 }
752 auto args_cur = args_vector.begin();
753
754 Value* value = nullptr; // Value to use, may point to result_value.
755 Value result_value; // Storage for the "evaluate" case.
756 Value scope_value; // Storage for an evaluated scope.
757 const IdentifierNode* identifier = (*args_cur)->AsIdentifier();
758 if (identifier) {
759 // Optimize the common case where the input scope is an identifier. This
760 // prevents a copy of a potentially large Scope object.
761 value = scope->GetMutableValue(identifier->value().value(),
762 Scope::SEARCH_NESTED, true);
763 if (!value) {
764 *err = Err(identifier, "Undefined identifier.");
765 return Value();
766 }
767 } else {
768 // Non-optimized case, just evaluate the argument.
769 result_value = (*args_cur)->Execute(scope, err);
770 if (err->has_error())
771 return Value();
772 value = &result_value;
773 }
774 args_cur++;
775
776 // Extract the source scope if different from current one.
777 Scope* source = scope;
778 if (value->type() == Value::SCOPE) {
779 if (args_cur == args_vector.end()) {
780 *err = Err(
781 function, "Wrong number of arguments.",
782 "The first argument is a scope, expecting two or three arguments.");
783 return Value();
784 }
785 // Copy the scope value if it will be overridden.
786 if (value == &result_value) {
787 scope_value = Value(nullptr, value->scope_value()->MakeClosure());
788 source = scope_value.scope_value();
789 } else {
790 source = value->scope_value();
791 }
792 result_value = (*args_cur)->Execute(scope, err);
793 if (err->has_error())
794 return Value();
795 value = &result_value;
796 args_cur++;
797 } else if (args_vector.size() > 2) {
798 *err = Err(
799 function, "Wrong number of arguments.",
800 "The first argument is not a scope, expecting one or two arguments.");
801 return Value();
802 }
803
804 // Extract the exclusion list if defined.
805 Value exclusion_value;
806 std::set<std::string> exclusion_set;
807 if (args_cur != args_vector.end()) {
808 exclusion_value = (*args_cur)->Execute(source, err);
809 if (err->has_error())
810 return Value();
811
812 if (exclusion_value.type() != Value::LIST) {
813 *err = Err(exclusion_value, "Not a valid list of variables to exclude.",
814 "Expecting a list of strings.");
815 return Value();
816 }
817
818 for (const Value& cur : exclusion_value.list_value()) {
819 if (!cur.VerifyTypeIs(Value::STRING, err))
820 return Value();
821
822 exclusion_set.insert(cur.string_value());
823 }
824 }
825
826 if (value->type() == Value::STRING) {
827 if (value->string_value() == "*") {
828 source->MarkAllUsed(exclusion_set);
829 return Value();
830 }
831 } else if (value->type() == Value::LIST) {
832 if (exclusion_value.type() != Value::NONE) {
833 *err = Err(exclusion_value, "Not supported with a variable list.",
834 "Exclusion list can only be used with the string \"*\".");
835 return Value();
836 }
837 for (const Value& cur : value->list_value()) {
838 if (!cur.VerifyTypeIs(Value::STRING, err))
839 return Value();
840 // We don't need the return value, we invoke scope::GetValue only to mark
841 // the value as used. Note that we cannot use Scope::MarkUsed because we
842 // want to also search in the parent scope.
843 (void)source->GetValue(cur.string_value(), true);
844 }
845 return Value();
846 }
847
848 // Not the right type of argument.
849 *err = Err(*value, "Not a valid list of variables.",
850 "Expecting either the string \"*\" or a list of strings.");
851 return Value();
852 }
853
854 // pool ------------------------------------------------------------------------
855
856 const char kPool[] = "pool";
857 const char kPool_HelpShort[] = "pool: Defines a pool object.";
858 const char kPool_Help[] =
859 R"*(pool: Defines a pool object.
860
861 Pool objects can be applied to a tool to limit the parallelism of the
862 build. This object has a single property "depth" corresponding to
863 the number of tasks that may run simultaneously.
864
865 As the file containing the pool definition may be executed in the
866 context of more than one toolchain it is recommended to specify an
867 explicit toolchain when defining and referencing a pool.
868
869 A pool named "console" defined in the root build file represents Ninja's
870 console pool. Targets using this pool will have access to the console's
871 stdin and stdout, and output will not be buffered. This special pool must
872 have a depth of 1. Pools not defined in the root must not be named "console".
873 The console pool can only be defined for the default toolchain.
874 Refer to the Ninja documentation on the console pool for more info.
875
876 A pool is referenced by its label just like a target.
877
878 Variables
879
880 depth*
881 * = required
882
883 Example
884
885 if (current_toolchain == default_toolchain) {
886 pool("link_pool") {
887 depth = 1
888 }
889 }
890
891 toolchain("toolchain") {
892 tool("link") {
893 command = "..."
894 pool = ":link_pool($default_toolchain)"
895 }
896 }
897 )*";
898
899 const char kDepth[] = "depth";
900
RunPool(const FunctionCallNode * function,const std::vector<Value> & args,Scope * scope,Err * err)901 Value RunPool(const FunctionCallNode* function,
902 const std::vector<Value>& args,
903 Scope* scope,
904 Err* err) {
905 NonNestableBlock non_nestable(scope, function, "pool");
906 if (!non_nestable.Enter(err))
907 return Value();
908
909 if (!EnsureSingleStringArg(function, args, err) ||
910 !EnsureNotProcessingImport(function, scope, err))
911 return Value();
912
913 Label label(MakeLabelForScope(scope, function, args[0].string_value()));
914
915 if (g_scheduler->verbose_logging())
916 g_scheduler->Log("Defining pool", label.GetUserVisibleName(true));
917
918 // Get the pool depth. It is an error to define a pool without a depth,
919 // so check first for the presence of the value.
920 const Value* depth = scope->GetValue(kDepth, true);
921 if (!depth) {
922 *err = Err(function, "Can't define a pool without depth.");
923 return Value();
924 }
925
926 if (!depth->VerifyTypeIs(Value::INTEGER, err))
927 return Value();
928
929 if (depth->int_value() < 0) {
930 *err = Err(*depth, "depth must be positive or 0.");
931 return Value();
932 }
933
934 // Create the new pool.
935 std::unique_ptr<Pool> pool = std::make_unique<Pool>(
936 scope->settings(), label, scope->build_dependency_files());
937
938 if (label.name() == "console") {
939 const Settings* settings = scope->settings();
940 if (!settings->is_default()) {
941 *err = Err(
942 function,
943 "\"console\" pool must be defined only in the default toolchain.");
944 return Value();
945 }
946 if (label.dir() != settings->build_settings()->root_target_label().dir()) {
947 *err = Err(function, "\"console\" pool must be defined in the root //.");
948 return Value();
949 }
950 if (depth->int_value() != 1) {
951 *err = Err(*depth, "\"console\" pool must have depth 1.");
952 return Value();
953 }
954 }
955 pool->set_depth(depth->int_value());
956
957 // Save the generated item.
958 Scope::ItemVector* collector = scope->GetItemCollector();
959 if (!collector) {
960 *err = Err(function, "Can't define a pool in this context.");
961 return Value();
962 }
963 collector->push_back(std::move(pool));
964
965 return Value();
966 }
967
968 // print -----------------------------------------------------------------------
969
970 const char kPrint[] = "print";
971 const char kPrint_HelpShort[] = "print: Prints to the console.";
972 const char kPrint_Help[] =
973 R"(print: Prints to the console.
974
975 Prints all arguments to the console separated by spaces. A newline is
976 automatically appended to the end.
977
978 This function is intended for debugging. Note that build files are run in
979 parallel so you may get interleaved prints. A buildfile may also be executed
980 more than once in parallel in the context of different toolchains so the
981 prints from one file may be duplicated or
982 interleaved with itself.
983
984 Examples
985
986 print("Hello world")
987
988 print(sources, deps)
989 )";
990
RunPrint(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)991 Value RunPrint(Scope* scope,
992 const FunctionCallNode* function,
993 const std::vector<Value>& args,
994 Err* err) {
995 std::string output;
996 for (size_t i = 0; i < args.size(); i++) {
997 if (i != 0)
998 output.push_back(' ');
999 output.append(args[i].ToString(false));
1000 }
1001 output.push_back('\n');
1002
1003 const BuildSettings::PrintCallback& cb =
1004 scope->settings()->build_settings()->print_callback();
1005 if (cb) {
1006 cb(output);
1007 } else {
1008 printf("%s", output.c_str());
1009 fflush(stdout);
1010 }
1011
1012 return Value();
1013 }
1014
1015 // print_stack_trace -----------------------------------------------------------
1016
1017 const char kPrintStackTrace[] = "print_stack_trace";
1018 const char kPrintStackTrace_HelpShort[] =
1019 "print_stack_trace: Prints a stack trace.";
1020 const char kPrintStackTrace_Help[] =
1021 R"(print_stack_trace: Prints a stack trace.
1022
1023 Prints the current file location, and all template invocations that led up to
1024 this location, to the console.
1025
1026 Examples
1027
1028 template("foo"){
1029 print_stack_trace()
1030 }
1031 template("bar"){
1032 foo(target_name + ".foo") {
1033 baz = invoker.baz
1034 }
1035 }
1036 bar("lala") {
1037 baz = 42
1038 }
1039
1040 will print out the following:
1041
1042 print_stack_trace() initiated at //build.gn:2
1043 bar("lala") //BUILD.gn:9
1044 foo("lala.foo") //BUILD.gn:5
1045 print_stack_trace() //BUILD.gn:2
1046
1047 )";
1048
RunPrintStackTrace(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)1049 Value RunPrintStackTrace(Scope* scope,
1050 const FunctionCallNode* function,
1051 const std::vector<Value>& args,
1052 Err* err) {
1053 std::string location_str = function->GetRange().begin().Describe(false);
1054 std::string toolchain =
1055 scope->settings()->toolchain_label().GetUserVisibleName(false);
1056 std::string output = "print_stack_trace() initiated at: " + location_str +
1057 " using: " + toolchain;
1058 output.push_back('\n');
1059
1060 for (const auto& entry : scope->GetTemplateInvocationEntries()) {
1061 output.append(" " + entry.Describe() + "\n");
1062 }
1063 output.append(" print_stack_trace() " + location_str + "\n");
1064
1065 const BuildSettings::PrintCallback& cb =
1066 scope->settings()->build_settings()->print_callback();
1067 if (cb) {
1068 cb(output);
1069 } else {
1070 printf("%s", output.c_str());
1071 fflush(stdout);
1072 }
1073
1074 return Value();
1075 }
1076
1077 // split_list ------------------------------------------------------------------
1078
1079 const char kSplitList[] = "split_list";
1080 const char kSplitList_HelpShort[] =
1081 "split_list: Splits a list into N different sub-lists.";
1082 const char kSplitList_Help[] =
1083 R"(split_list: Splits a list into N different sub-lists.
1084
1085 result = split_list(input, n)
1086
1087 Given a list and a number N, splits the list into N sub-lists of
1088 approximately equal size. The return value is a list of the sub-lists. The
1089 result will always be a list of size N. If N is greater than the number of
1090 elements in the input, it will be padded with empty lists.
1091
1092 The expected use is to divide source files into smaller uniform chunks.
1093
1094 Example
1095
1096 The code:
1097 mylist = [1, 2, 3, 4, 5, 6]
1098 print(split_list(mylist, 3))
1099
1100 Will print:
1101 [[1, 2], [3, 4], [5, 6]
1102 )";
RunSplitList(Scope * scope,const FunctionCallNode * function,const ListNode * args_list,Err * err)1103 Value RunSplitList(Scope* scope,
1104 const FunctionCallNode* function,
1105 const ListNode* args_list,
1106 Err* err) {
1107 const auto& args_vector = args_list->contents();
1108 if (args_vector.size() != 2) {
1109 *err = Err(function, "Wrong number of arguments to split_list().",
1110 "Expecting exactly two.");
1111 return Value();
1112 }
1113
1114 ParseNodeValueAdapter list_adapter;
1115 if (!list_adapter.InitForType(scope, args_vector[0].get(), Value::LIST, err))
1116 return Value();
1117 const std::vector<Value>& input = list_adapter.get().list_value();
1118
1119 ParseNodeValueAdapter count_adapter;
1120 if (!count_adapter.InitForType(scope, args_vector[1].get(), Value::INTEGER,
1121 err))
1122 return Value();
1123 int64_t count = count_adapter.get().int_value();
1124 if (count <= 0) {
1125 *err = Err(function, "Requested result size is not positive.");
1126 return Value();
1127 }
1128
1129 Value result(function, Value::LIST);
1130 result.list_value().resize(count);
1131
1132 // Every result list gets at least this many items in it.
1133 int64_t min_items_per_list = static_cast<int64_t>(input.size()) / count;
1134
1135 // This many result lists get an extra item which is the remainder from above.
1136 int64_t extra_items = static_cast<int64_t>(input.size()) % count;
1137
1138 // Allocate all lists that have a remainder assigned to them (max items).
1139 int64_t max_items_per_list = min_items_per_list + 1;
1140 auto last_item_end = input.begin();
1141 for (int64_t i = 0; i < extra_items; i++) {
1142 result.list_value()[i] = Value(function, Value::LIST);
1143
1144 auto begin_add = last_item_end;
1145 last_item_end += max_items_per_list;
1146 result.list_value()[i].list_value().assign(begin_add, last_item_end);
1147 }
1148
1149 // Allocate all smaller items that don't have a remainder.
1150 for (int64_t i = extra_items; i < count; i++) {
1151 result.list_value()[i] = Value(function, Value::LIST);
1152
1153 auto begin_add = last_item_end;
1154 last_item_end += min_items_per_list;
1155 result.list_value()[i].list_value().assign(begin_add, last_item_end);
1156 }
1157
1158 return result;
1159 }
1160
1161 // string_join -----------------------------------------------------------------
1162
1163 const char kStringJoin[] = "string_join";
1164 const char kStringJoin_HelpShort[] =
1165 "string_join: Concatenates a list of strings with a separator.";
1166 const char kStringJoin_Help[] =
1167 R"(string_join: Concatenates a list of strings with a separator.
1168
1169 result = string_join(separator, strings)
1170
1171 Concatenate a list of strings with intervening occurrences of separator.
1172
1173 Examples
1174
1175 string_join("", ["a", "b", "c"]) --> "abc"
1176 string_join("|", ["a", "b", "c"]) --> "a|b|c"
1177 string_join(", ", ["a", "b", "c"]) --> "a, b, c"
1178 string_join("s", ["", ""]) --> "s"
1179 )";
1180
RunStringJoin(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)1181 Value RunStringJoin(Scope* scope,
1182 const FunctionCallNode* function,
1183 const std::vector<Value>& args,
1184 Err* err) {
1185 // Check usage: Number of arguments.
1186 if (args.size() != 2) {
1187 *err = Err(function, "Wrong number of arguments to string_join().",
1188 "Expecting exactly two. usage: string_join(separator, strings)");
1189 return Value();
1190 }
1191
1192 // Check usage: separator is a string.
1193 if (!args[0].VerifyTypeIs(Value::STRING, err)) {
1194 *err = Err(function,
1195 "separator in string_join(separator, strings) is not "
1196 "a string",
1197 "Expecting separator argument to be a string.");
1198 return Value();
1199 }
1200 const std::string separator = args[0].string_value();
1201
1202 // Check usage: strings is a list.
1203 if (!args[1].VerifyTypeIs(Value::LIST, err)) {
1204 *err = Err(function,
1205 "strings in string_join(separator, strings) "
1206 "is not a list",
1207 "Expecting strings argument to be a list.");
1208 return Value();
1209 }
1210 const std::vector<Value> strings = args[1].list_value();
1211
1212 // Arguments looks good; do the join.
1213 std::stringstream stream;
1214 for (size_t i = 0; i < strings.size(); ++i) {
1215 if (!strings[i].VerifyTypeIs(Value::STRING, err)) {
1216 return Value();
1217 }
1218 if (i != 0) {
1219 stream << separator;
1220 }
1221 stream << strings[i].string_value();
1222 }
1223 return Value(function, stream.str());
1224 }
1225
1226 // string_replace --------------------------------------------------------------
1227
1228 const char kStringReplace[] = "string_replace";
1229 const char kStringReplace_HelpShort[] =
1230 "string_replace: Replaces substring in the given string.";
1231 const char kStringReplace_Help[] =
1232 R"(string_replace: Replaces substring in the given string.
1233
1234 result = string_replace(str, old, new[, max])
1235
1236 Returns a copy of the string str in which the occurrences of old have been
1237 replaced with new, optionally restricting the number of replacements. The
1238 replacement is performed sequentially, so if new contains old, it won't be
1239 replaced.
1240
1241 Example
1242
1243 The code:
1244 mystr = "Hello, world!"
1245 print(string_replace(mystr, "world", "GN"))
1246
1247 Will print:
1248 Hello, GN!
1249 )";
1250
RunStringReplace(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)1251 Value RunStringReplace(Scope* scope,
1252 const FunctionCallNode* function,
1253 const std::vector<Value>& args,
1254 Err* err) {
1255 if (args.size() < 3 || args.size() > 4) {
1256 *err = Err(function, "Wrong number of arguments to string_replace().");
1257 return Value();
1258 }
1259
1260 if (!args[0].VerifyTypeIs(Value::STRING, err))
1261 return Value();
1262 const std::string str = args[0].string_value();
1263
1264 if (!args[1].VerifyTypeIs(Value::STRING, err))
1265 return Value();
1266 const std::string& old = args[1].string_value();
1267
1268 if (!args[2].VerifyTypeIs(Value::STRING, err))
1269 return Value();
1270 const std::string& new_ = args[2].string_value();
1271
1272 int64_t max = INT64_MAX;
1273 if (args.size() > 3) {
1274 if (!args[3].VerifyTypeIs(Value::INTEGER, err))
1275 return Value();
1276 max = args[3].int_value();
1277 if (max <= 0) {
1278 *err = Err(function, "Requested number of replacements is not positive.");
1279 return Value();
1280 }
1281 }
1282
1283 int64_t n = 0;
1284 std::string val(str);
1285 size_t start_pos = 0;
1286 while ((start_pos = val.find(old, start_pos)) != std::string::npos) {
1287 val.replace(start_pos, old.length(), new_);
1288 start_pos += new_.length();
1289 if (++n >= max)
1290 break;
1291 }
1292 return Value(function, std::move(val));
1293 }
1294
1295 // string_split ----------------------------------------------------------------
1296
1297 const char kStringSplit[] = "string_split";
1298 const char kStringSplit_HelpShort[] =
1299 "string_split: Split string into a list of strings.";
1300 const char kStringSplit_Help[] =
1301 R"(string_split: Split string into a list of strings.
1302
1303 result = string_split(str[, sep])
1304
1305 Split string into all substrings separated by separator and returns a list
1306 of the substrings between those separators.
1307
1308 If the separator argument is omitted, the split is by any whitespace, and
1309 any leading/trailing whitespace is ignored; similar to Python's str.split().
1310
1311 Examples without a separator (split on whitespace):
1312
1313 string_split("") --> []
1314 string_split("a") --> ["a"]
1315 string_split(" aa bb") --> ["aa", "bb"]
1316
1317 Examples with a separator (split on separators):
1318
1319 string_split("", "|") --> [""]
1320 string_split(" a b ", " ") --> ["", "", "a", "b", "", ""]
1321 string_split("aa+-bb+-c", "+-") --> ["aa", "bb", "c"]
1322 )";
1323
RunStringSplit(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)1324 Value RunStringSplit(Scope* scope,
1325 const FunctionCallNode* function,
1326 const std::vector<Value>& args,
1327 Err* err) {
1328 // Check usage: argument count.
1329 if (args.size() != 1 && args.size() != 2) {
1330 *err = Err(function, "Wrong number of arguments to string_split().",
1331 "Usage: string_split(str[, sep])");
1332 return Value();
1333 }
1334
1335 // Check usage: str is a string.
1336 if (!args[0].VerifyTypeIs(Value::STRING, err)) {
1337 return Value();
1338 }
1339 const std::string str = args[0].string_value();
1340
1341 // Check usage: separator is a non-empty string.
1342 std::string separator;
1343 if (args.size() == 2) {
1344 if (!args[1].VerifyTypeIs(Value::STRING, err)) {
1345 return Value();
1346 }
1347 separator = args[1].string_value();
1348 if (separator.empty()) {
1349 *err = Err(function,
1350 "Separator argument to string_split() "
1351 "cannot be empty string",
1352 "Usage: string_split(str[, sep])");
1353 return Value();
1354 }
1355 }
1356
1357 // Split the string into a std::vector.
1358 std::vector<std::string> strings;
1359 if (!separator.empty()) {
1360 // Case: Explicit separator argument.
1361 // Note: split_string("", "x") --> [""] like Python.
1362 size_t pos = 0;
1363 size_t next_pos = 0;
1364 while ((next_pos = str.find(separator, pos)) != std::string::npos) {
1365 strings.push_back(str.substr(pos, next_pos - pos));
1366 pos = next_pos + separator.length();
1367 }
1368 strings.push_back(str.substr(pos, std::string::npos));
1369 } else {
1370 // Case: Split on any whitespace and strip ends.
1371 // Note: split_string("") --> [] like Python.
1372 std::string::const_iterator pos = str.cbegin();
1373 while (pos != str.end()) {
1374 // Advance past spaces. After this, pos is pointing to non-whitespace.
1375 pos = find_if(pos, str.end(), [](char x) { return !std::isspace(x); });
1376 if (pos == str.end()) {
1377 // Tail is all whitespace, so we're done.
1378 break;
1379 }
1380 // Advance past non-whitespace to get next chunk.
1381 std::string::const_iterator next_whitespace_position =
1382 find_if(pos, str.end(), [](char x) { return std::isspace(x); });
1383 strings.push_back(std::string(pos, next_whitespace_position));
1384 pos = next_whitespace_position;
1385 }
1386 }
1387
1388 // Convert vector of std::strings to list of GN strings.
1389 Value result(function, Value::LIST);
1390 result.list_value().resize(strings.size());
1391 for (size_t i = 0; i < strings.size(); ++i) {
1392 result.list_value()[i] = Value(function, strings[i]);
1393 }
1394 return result;
1395 }
1396
1397 // -----------------------------------------------------------------------------
1398
FunctionInfo()1399 FunctionInfo::FunctionInfo()
1400 : self_evaluating_args_runner(nullptr),
1401 generic_block_runner(nullptr),
1402 executed_block_runner(nullptr),
1403 no_block_runner(nullptr),
1404 help_short(nullptr),
1405 help(nullptr),
1406 is_target(false) {}
1407
FunctionInfo(SelfEvaluatingArgsFunction seaf,const char * in_help_short,const char * in_help,bool in_is_target)1408 FunctionInfo::FunctionInfo(SelfEvaluatingArgsFunction seaf,
1409 const char* in_help_short,
1410 const char* in_help,
1411 bool in_is_target)
1412 : self_evaluating_args_runner(seaf),
1413 generic_block_runner(nullptr),
1414 executed_block_runner(nullptr),
1415 no_block_runner(nullptr),
1416 help_short(in_help_short),
1417 help(in_help),
1418 is_target(in_is_target) {}
1419
FunctionInfo(GenericBlockFunction gbf,const char * in_help_short,const char * in_help,bool in_is_target)1420 FunctionInfo::FunctionInfo(GenericBlockFunction gbf,
1421 const char* in_help_short,
1422 const char* in_help,
1423 bool in_is_target)
1424 : self_evaluating_args_runner(nullptr),
1425 generic_block_runner(gbf),
1426 executed_block_runner(nullptr),
1427 no_block_runner(nullptr),
1428 help_short(in_help_short),
1429 help(in_help),
1430 is_target(in_is_target) {}
1431
FunctionInfo(ExecutedBlockFunction ebf,const char * in_help_short,const char * in_help,bool in_is_target)1432 FunctionInfo::FunctionInfo(ExecutedBlockFunction ebf,
1433 const char* in_help_short,
1434 const char* in_help,
1435 bool in_is_target)
1436 : self_evaluating_args_runner(nullptr),
1437 generic_block_runner(nullptr),
1438 executed_block_runner(ebf),
1439 no_block_runner(nullptr),
1440 help_short(in_help_short),
1441 help(in_help),
1442 is_target(in_is_target) {}
1443
FunctionInfo(NoBlockFunction nbf,const char * in_help_short,const char * in_help,bool in_is_target)1444 FunctionInfo::FunctionInfo(NoBlockFunction nbf,
1445 const char* in_help_short,
1446 const char* in_help,
1447 bool in_is_target)
1448 : self_evaluating_args_runner(nullptr),
1449 generic_block_runner(nullptr),
1450 executed_block_runner(nullptr),
1451 no_block_runner(nbf),
1452 help_short(in_help_short),
1453 help(in_help),
1454 is_target(in_is_target) {}
1455
1456 // Setup the function map via a static initializer. We use this because it
1457 // avoids race conditions without having to do some global setup function or
1458 // locking-heavy singleton checks at runtime. In practice, we always need this
1459 // before we can do anything interesting, so it's OK to wait for the
1460 // initializer.
1461 struct FunctionInfoInitializer {
1462 FunctionInfoMap map;
1463
FunctionInfoInitializerfunctions::FunctionInfoInitializer1464 FunctionInfoInitializer() {
1465 #define INSERT_FUNCTION(command, is_target) \
1466 map[k##command] = FunctionInfo(&Run##command, k##command##_HelpShort, \
1467 k##command##_Help, is_target);
1468
1469 INSERT_FUNCTION(Action, true)
1470 INSERT_FUNCTION(ActionForEach, true)
1471 INSERT_FUNCTION(BundleData, true)
1472 INSERT_FUNCTION(CreateBundle, true)
1473 INSERT_FUNCTION(Copy, true)
1474 INSERT_FUNCTION(Executable, true)
1475 INSERT_FUNCTION(Group, true)
1476 INSERT_FUNCTION(LoadableModule, true)
1477 INSERT_FUNCTION(SharedLibrary, true)
1478 INSERT_FUNCTION(SourceSet, true)
1479 INSERT_FUNCTION(StaticLibrary, true)
1480 INSERT_FUNCTION(Target, true)
1481 INSERT_FUNCTION(GeneratedFile, true)
1482 INSERT_FUNCTION(RustLibrary, true)
1483 INSERT_FUNCTION(RustProcMacro, true)
1484
1485 INSERT_FUNCTION(Assert, false)
1486 INSERT_FUNCTION(Config, false)
1487 INSERT_FUNCTION(DeclareArgs, false)
1488 INSERT_FUNCTION(Defined, false)
1489 INSERT_FUNCTION(ExecScript, false)
1490 INSERT_FUNCTION(FilterExclude, false)
1491 INSERT_FUNCTION(FilterInclude, false)
1492 INSERT_FUNCTION(FilterLabelsInclude, false)
1493 INSERT_FUNCTION(FilterLabelsExclude, false)
1494 INSERT_FUNCTION(ForEach, false)
1495 INSERT_FUNCTION(ForwardVariablesFrom, false)
1496 INSERT_FUNCTION(GetEnv, false)
1497 INSERT_FUNCTION(GetLabelInfo, false)
1498 INSERT_FUNCTION(GetPathInfo, false)
1499 INSERT_FUNCTION(GetTargetOutputs, false)
1500 INSERT_FUNCTION(Import, false)
1501 INSERT_FUNCTION(LabelMatches, false)
1502 INSERT_FUNCTION(NotNeeded, false)
1503 INSERT_FUNCTION(Pool, false)
1504 INSERT_FUNCTION(Print, false)
1505 INSERT_FUNCTION(PrintStackTrace, false)
1506 INSERT_FUNCTION(ProcessFileTemplate, false)
1507 INSERT_FUNCTION(ReadFile, false)
1508 INSERT_FUNCTION(RebasePath, false)
1509 INSERT_FUNCTION(SetDefaults, false)
1510 INSERT_FUNCTION(SetDefaultToolchain, false)
1511 INSERT_FUNCTION(SplitList, false)
1512 INSERT_FUNCTION(StringJoin, false)
1513 INSERT_FUNCTION(StringReplace, false)
1514 INSERT_FUNCTION(StringSplit, false)
1515 INSERT_FUNCTION(Template, false)
1516 INSERT_FUNCTION(Tool, false)
1517 INSERT_FUNCTION(Toolchain, false)
1518 INSERT_FUNCTION(WriteFile, false)
1519
1520 #undef INSERT_FUNCTION
1521 }
1522 };
1523 const FunctionInfoInitializer function_info;
1524
GetFunctions()1525 const FunctionInfoMap& GetFunctions() {
1526 return function_info.map;
1527 }
1528
RunFunction(Scope * scope,const FunctionCallNode * function,const ListNode * args_list,BlockNode * block,Err * err)1529 Value RunFunction(Scope* scope,
1530 const FunctionCallNode* function,
1531 const ListNode* args_list,
1532 BlockNode* block,
1533 Err* err) {
1534 const Token& name = function->function();
1535
1536 std::string template_name(function->function().value());
1537 const Template* templ = scope->GetTemplate(template_name);
1538 if (templ) {
1539 Value args = args_list->Execute(scope, err);
1540 if (err->has_error())
1541 return Value();
1542 return templ->Invoke(scope, function, template_name, args.list_value(),
1543 block, err);
1544 }
1545
1546 // No template matching this, check for a built-in function.
1547 const FunctionInfoMap& function_map = GetFunctions();
1548 FunctionInfoMap::const_iterator found_function =
1549 function_map.find(name.value());
1550 if (found_function == function_map.end()) {
1551 *err = Err(name, "Unknown function.");
1552 return Value();
1553 }
1554
1555 if (found_function->second.self_evaluating_args_runner) {
1556 // Self evaluating args functions are special weird built-ins like foreach.
1557 // Rather than force them all to check that they have a block or no block
1558 // and risk bugs for new additions, check a whitelist here.
1559 if (found_function->second.self_evaluating_args_runner != &RunForEach) {
1560 if (!VerifyNoBlockForFunctionCall(function, block, err))
1561 return Value();
1562 }
1563 return found_function->second.self_evaluating_args_runner(scope, function,
1564 args_list, err);
1565 }
1566
1567 // All other function types take a pre-executed set of args.
1568 Value args = args_list->Execute(scope, err);
1569 if (err->has_error())
1570 return Value();
1571
1572 if (found_function->second.generic_block_runner) {
1573 if (!block) {
1574 FillNeedsBlockError(function, err);
1575 return Value();
1576 }
1577 return found_function->second.generic_block_runner(
1578 scope, function, args.list_value(), block, err);
1579 }
1580
1581 if (found_function->second.executed_block_runner) {
1582 if (!block) {
1583 FillNeedsBlockError(function, err);
1584 return Value();
1585 }
1586
1587 Scope block_scope(scope);
1588 block->Execute(&block_scope, err);
1589 if (err->has_error())
1590 return Value();
1591
1592 Value result = found_function->second.executed_block_runner(
1593 function, args.list_value(), &block_scope, err);
1594 if (err->has_error())
1595 return Value();
1596
1597 if (!block_scope.CheckForUnusedVars(err))
1598 return Value();
1599 return result;
1600 }
1601
1602 // Otherwise it's a no-block function.
1603 if (!VerifyNoBlockForFunctionCall(function, block, err))
1604 return Value();
1605 return found_function->second.no_block_runner(scope, function,
1606 args.list_value(), err);
1607 }
1608
1609 } // namespace functions
1610