Add utility functions needed for rect-based event targeting
[chromium-blink-merge.git] / tools / gn / function_set_defaults.cc
blob45c6fc59edbdfbfb791795a2f10e182f3e1dd9af
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.
5 #include "tools/gn/err.h"
6 #include "tools/gn/functions.h"
7 #include "tools/gn/parse_tree.h"
8 #include "tools/gn/scope.h"
10 namespace functions {
12 const char kSetDefaults[] = "set_defaults";
13 const char kSetDefaults_Help[] =
14 "set_defaults: Set default values for a target type.\n"
15 "\n"
16 " set_defaults(<target_type_name>) { <values...> }\n"
17 "\n"
18 " Sets the default values for a given target type. Whenever\n"
19 " target_type_name is seen in the future, the values specified in\n"
20 " set_default's block will be copied into the current scope.\n"
21 "\n"
22 " When the target type is used, the variable copying is very strict.\n"
23 " If a variable with that name is already in scope, the build will fail\n"
24 " with an error.\n"
25 "\n"
26 " set_defaults can be used for built-in target types (\"executable\",\n"
27 " \"shared_library\", etc.) and custom ones defined via the \"template\"\n"
28 " command.\n"
29 "\n"
30 "Example:\n"
31 " set_defaults(\"static_library\") {\n"
32 " configs = [ \"//tools/mything:settings\" ]\n"
33 " }\n"
34 "\n"
35 " static_library(\"mylib\")\n"
36 " # The configs will be auto-populated as above. You can remove it if\n"
37 " # you don't want the default for a particular default:\n"
38 " configs -= \"//tools/mything:setgings\"\n"
39 " }\n";
41 Value RunSetDefaults(Scope* scope,
42 const FunctionCallNode* function,
43 const std::vector<Value>& args,
44 BlockNode* block,
45 Err* err) {
46 if (!EnsureSingleStringArg(function, args, err))
47 return Value();
48 const std::string& target_type(args[0].string_value());
50 // Ensure there aren't defaults already set.
52 // It might be nice to allow multiple calls set mutate the defaults. The
53 // main case for this is where some local portions of the code want
54 // additional defaults they specify in an imported file.
56 // Currently, we don't allow imports to clobber anything, so this wouldn't
57 // work. Additionally, allowing this would be undesirable since we don't
58 // want multiple imports to each try to set defaults, since it might look
59 // like the defaults are modified by each one in sequence, while in fact
60 // imports would always clobber previous values and it would be confusing.
62 // If we wanted this, the solution would be to allow imports to overwrite
63 // target defaults set up by the default build config only. That way there
64 // are no ordering issues, but this would be more work.
65 if (scope->GetTargetDefaults(target_type)) {
66 *err = Err(function->function(),
67 "This target type defaults were already set.");
68 return Value();
71 if (!block) {
72 FillNeedsBlockError(function, err);
73 return Value();
76 // Run the block for the rule invocation.
77 Scope block_scope(scope);
78 block->ExecuteBlockInScope(&block_scope, err);
79 if (err->has_error())
80 return Value();
82 // Now copy the values set on the scope we made into the free-floating one
83 // (with no containing scope) used to hold the target defaults.
84 Scope* dest = scope->MakeTargetDefaults(target_type);
85 block_scope.NonRecursiveMergeTo(dest, function, "<SHOULD NOT FAIL>", err);
86 return Value();
89 } // namespace functions