| // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef TOOLS_GN_FUNCTIONS_H_ |
| #define TOOLS_GN_FUNCTIONS_H_ |
| |
| #include <map> |
| #include <string> |
| #include <string_view> |
| #include <vector> |
| |
| class Err; |
| class BlockNode; |
| class FunctionCallNode; |
| class Label; |
| class ListNode; |
| class ParseNode; |
| class Scope; |
| class Value; |
| |
| // ----------------------------------------------------------------------------- |
| |
| namespace functions { |
| |
| // This type of function invocation has no block and evaluates its arguments |
| // itself rather than taking a pre-executed list. This allows us to implement |
| // certain built-in functions. |
| using SelfEvaluatingArgsFunction = Value (*)(Scope* scope, |
| const FunctionCallNode* function, |
| const ListNode* args_list, |
| Err* err); |
| |
| // This type of function invocation takes a block node that it will execute. |
| using GenericBlockFunction = Value (*)(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| // This type of function takes a block, but does not need to control execution |
| // of it. The dispatch function will pre-execute the block and pass the |
| // resulting block_scope to the function. |
| using ExecutedBlockFunction = Value (*)(const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Scope* block_scope, |
| Err* err); |
| |
| // This type of function does not take a block. It just has arguments. |
| using NoBlockFunction = Value (*)(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kAction[]; |
| extern const char kAction_HelpShort[]; |
| extern const char kAction_Help[]; |
| Value RunAction(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kActionForEach[]; |
| extern const char kActionForEach_HelpShort[]; |
| extern const char kActionForEach_Help[]; |
| Value RunActionForEach(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kAssert[]; |
| extern const char kAssert_HelpShort[]; |
| extern const char kAssert_Help[]; |
| Value RunAssert(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kBundleData[]; |
| extern const char kBundleData_HelpShort[]; |
| extern const char kBundleData_Help[]; |
| Value RunBundleData(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kCreateBundle[]; |
| extern const char kCreateBundle_HelpShort[]; |
| extern const char kCreateBundle_Help[]; |
| Value RunCreateBundle(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kConfig[]; |
| extern const char kConfig_HelpShort[]; |
| extern const char kConfig_Help[]; |
| Value RunConfig(const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Scope* block_scope, |
| Err* err); |
| |
| extern const char kCopy[]; |
| extern const char kCopy_HelpShort[]; |
| extern const char kCopy_Help[]; |
| Value RunCopy(const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Scope* block_scope, |
| Err* err); |
| |
| extern const char kDeclareArgs[]; |
| extern const char kDeclareArgs_HelpShort[]; |
| extern const char kDeclareArgs_Help[]; |
| Value RunDeclareArgs(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kDefined[]; |
| extern const char kDefined_HelpShort[]; |
| extern const char kDefined_Help[]; |
| Value RunDefined(Scope* scope, |
| const FunctionCallNode* function, |
| const ListNode* args_list, |
| Err* err); |
| |
| extern const char kExecScript[]; |
| extern const char kExecScript_HelpShort[]; |
| extern const char kExecScript_Help[]; |
| Value RunExecScript(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kExecutable[]; |
| extern const char kExecutable_HelpShort[]; |
| extern const char kExecutable_Help[]; |
| Value RunExecutable(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kForEach[]; |
| extern const char kForEach_HelpShort[]; |
| extern const char kForEach_Help[]; |
| Value RunForEach(Scope* scope, |
| const FunctionCallNode* function, |
| const ListNode* args_list, |
| Err* err); |
| |
| extern const char kForwardVariablesFrom[]; |
| extern const char kForwardVariablesFrom_HelpShort[]; |
| extern const char kForwardVariablesFrom_Help[]; |
| Value RunForwardVariablesFrom(Scope* scope, |
| const FunctionCallNode* function, |
| const ListNode* args_list, |
| Err* err); |
| |
| extern const char kGetEnv[]; |
| extern const char kGetEnv_HelpShort[]; |
| extern const char kGetEnv_Help[]; |
| Value RunGetEnv(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kGetLabelInfo[]; |
| extern const char kGetLabelInfo_HelpShort[]; |
| extern const char kGetLabelInfo_Help[]; |
| Value RunGetLabelInfo(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kGetPathInfo[]; |
| extern const char kGetPathInfo_HelpShort[]; |
| extern const char kGetPathInfo_Help[]; |
| Value RunGetPathInfo(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kGetTargetOutputs[]; |
| extern const char kGetTargetOutputs_HelpShort[]; |
| extern const char kGetTargetOutputs_Help[]; |
| Value RunGetTargetOutputs(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kGeneratedFile[]; |
| extern const char kGeneratedFile_HelpShort[]; |
| extern const char kGeneratedFile_Help[]; |
| Value RunGeneratedFile(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kGroup[]; |
| extern const char kGroup_HelpShort[]; |
| extern const char kGroup_Help[]; |
| Value RunGroup(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kImport[]; |
| extern const char kImport_HelpShort[]; |
| extern const char kImport_Help[]; |
| Value RunImport(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kLoadableModule[]; |
| extern const char kLoadableModule_HelpShort[]; |
| extern const char kLoadableModule_Help[]; |
| Value RunLoadableModule(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kNotNeeded[]; |
| extern const char kNotNeeded_HelpShort[]; |
| extern const char kNotNeeded_Help[]; |
| Value RunNotNeeded(Scope* scope, |
| const FunctionCallNode* function, |
| const ListNode* args_list, |
| Err* err); |
| |
| extern const char kPool[]; |
| extern const char kPool_HelpShort[]; |
| extern const char kPool_Help[]; |
| Value RunPool(const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Scope* block_scope, |
| Err* err); |
| |
| extern const char kPrint[]; |
| extern const char kPrint_HelpShort[]; |
| extern const char kPrint_Help[]; |
| Value RunPrint(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kProcessFileTemplate[]; |
| extern const char kProcessFileTemplate_HelpShort[]; |
| extern const char kProcessFileTemplate_Help[]; |
| Value RunProcessFileTemplate(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kReadFile[]; |
| extern const char kReadFile_HelpShort[]; |
| extern const char kReadFile_Help[]; |
| Value RunReadFile(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kRebasePath[]; |
| extern const char kRebasePath_HelpShort[]; |
| extern const char kRebasePath_Help[]; |
| Value RunRebasePath(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kRustLibrary[]; |
| extern const char kRustLibrary_HelpShort[]; |
| extern const char kRustLibrary_Help[]; |
| Value RunRustLibrary(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kSetDefaults[]; |
| extern const char kSetDefaults_HelpShort[]; |
| extern const char kSetDefaults_Help[]; |
| Value RunSetDefaults(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kSetDefaultToolchain[]; |
| extern const char kSetDefaultToolchain_HelpShort[]; |
| extern const char kSetDefaultToolchain_Help[]; |
| Value RunSetDefaultToolchain(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kSetSourcesAssignmentFilter[]; |
| extern const char kSetSourcesAssignmentFilter_HelpShort[]; |
| extern const char kSetSourcesAssignmentFilter_Help[]; |
| Value RunSetSourcesAssignmentFilter(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| extern const char kSharedLibrary[]; |
| extern const char kSharedLibrary_HelpShort[]; |
| extern const char kSharedLibrary_Help[]; |
| Value RunSharedLibrary(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kSourceSet[]; |
| extern const char kSourceSet_HelpShort[]; |
| extern const char kSourceSet_Help[]; |
| Value RunSourceSet(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kSplitList[]; |
| extern const char kSplitList_HelpShort[]; |
| extern const char kSplitList_Help[]; |
| Value RunSplitList(Scope* scope, |
| const FunctionCallNode* function, |
| const ListNode* args_list, |
| Err* err); |
| |
| extern const char kStaticLibrary[]; |
| extern const char kStaticLibrary_HelpShort[]; |
| extern const char kStaticLibrary_Help[]; |
| Value RunStaticLibrary(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kReplaceSubstr[]; |
| extern const char kReplaceSubstr_HelpShort[]; |
| extern const char kReplaceSubstr_Help[]; |
| Value RunReplaceSubstr(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args_list, |
| Err* err); |
| |
| extern const char kTarget[]; |
| extern const char kTarget_HelpShort[]; |
| extern const char kTarget_Help[]; |
| Value RunTarget(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kTemplate[]; |
| extern const char kTemplate_HelpShort[]; |
| extern const char kTemplate_Help[]; |
| Value RunTemplate(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kTool[]; |
| extern const char kTool_HelpShort[]; |
| extern const char kTool_Help[]; |
| Value RunTool(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kToolchain[]; |
| extern const char kToolchain_HelpShort[]; |
| extern const char kToolchain_Help[]; |
| Value RunToolchain(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err); |
| |
| extern const char kWriteFile[]; |
| extern const char kWriteFile_HelpShort[]; |
| extern const char kWriteFile_Help[]; |
| Value RunWriteFile(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| // ----------------------------------------------------------------------------- |
| |
| // One function record. Only one of the given runner types will be non-null |
| // which indicates the type of function it is. |
| struct FunctionInfo { |
| FunctionInfo(); |
| FunctionInfo(SelfEvaluatingArgsFunction seaf, |
| const char* in_help_short, |
| const char* in_help, |
| bool in_is_target); |
| FunctionInfo(GenericBlockFunction gbf, |
| const char* in_help_short, |
| const char* in_help, |
| bool in_is_target); |
| FunctionInfo(ExecutedBlockFunction ebf, |
| const char* in_help_short, |
| const char* in_help, |
| bool in_is_target); |
| FunctionInfo(NoBlockFunction nbf, |
| const char* in_help_short, |
| const char* in_help, |
| bool in_is_target); |
| |
| SelfEvaluatingArgsFunction self_evaluating_args_runner; |
| GenericBlockFunction generic_block_runner; |
| ExecutedBlockFunction executed_block_runner; |
| NoBlockFunction no_block_runner; |
| |
| const char* help_short; |
| const char* help; |
| |
| bool is_target; |
| }; |
| |
| using FunctionInfoMap = std::map<std::string_view, FunctionInfo>; |
| |
| // Returns the mapping of all built-in functions. |
| const FunctionInfoMap& GetFunctions(); |
| |
| // Runs the given function. |
| Value RunFunction(Scope* scope, |
| const FunctionCallNode* function, |
| const ListNode* args_list, |
| BlockNode* block, // Optional. |
| Err* err); |
| |
| } // namespace functions |
| |
| // Helper functions ----------------------------------------------------------- |
| |
| // Validates that the scope that a value is defined in is not the scope |
| // of the current declare_args() call, if that's what we're in. It is |
| // illegal to read a value from inside the same declare_args() call, since |
| // the overrides will not have been applied yet (see `gn help declare_args` |
| // for more). |
| bool EnsureNotReadingFromSameDeclareArgs(const ParseNode* node, |
| const Scope* cur_scope, |
| const Scope* val_scope, |
| Err* err); |
| |
| // Verifies that the current scope is not processing an import. If it is, it |
| // will set the error, blame the given parse node for it, and return false. |
| bool EnsureNotProcessingImport(const ParseNode* node, |
| const Scope* scope, |
| Err* err); |
| |
| // Like EnsureNotProcessingImport but checks for running the build config. |
| bool EnsureNotProcessingBuildConfig(const ParseNode* node, |
| const Scope* scope, |
| Err* err); |
| |
| // Sets up the |block_scope| for executing a target (or something like it). |
| // The |scope| is the containing scope. It should have been already set as the |
| // parent for the |block_scope| when the |block_scope| was created. |
| // |
| // This will set up the target defaults and set the |target_name| variable in |
| // the block scope to the current target name, which is assumed to be the first |
| // argument to the function. |
| // |
| // On success, returns true. On failure, sets the error and returns false. |
| bool 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); |
| |
| // Sets the given error to a message explaining that the function call requires |
| // a block. |
| void FillNeedsBlockError(const FunctionCallNode* function, Err* err); |
| |
| // Validates that the given function call has one string argument. This is |
| // the most common function signature, so it saves space to have this helper. |
| // Returns false and sets the error on failure. |
| bool EnsureSingleStringArg(const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| Err* err); |
| |
| // Returns the name of the toolchain for the given scope. |
| const Label& ToolchainLabelForScope(const Scope* scope); |
| |
| // Generates a label for the given scope, using the current directory and |
| // toolchain, and the given name. |
| Label MakeLabelForScope(const Scope* scope, |
| const FunctionCallNode* function, |
| const std::string& name); |
| |
| // Some types of blocks can't be nested inside other ones. For such cases, |
| // instantiate this object upon entering the block and Enter() will fail if |
| // there is already another non-nestable block on the stack. |
| class NonNestableBlock { |
| public: |
| // type_description is a string that will be used in error messages |
| // describing the type of the block, for example, "template" or "config". |
| NonNestableBlock(Scope* scope, |
| const FunctionCallNode* function, |
| const char* type_description); |
| ~NonNestableBlock(); |
| |
| bool Enter(Err* err); |
| |
| private: |
| // Used as a void* key for the Scope to track our property. The actual value |
| // is never used. |
| static const int kKey; |
| |
| Scope* scope_; |
| const FunctionCallNode* function_; |
| const char* type_description_; |
| |
| // Set to true when the key is added to the scope so we don't try to |
| // delete nonexistant keys which will cause assertions. |
| bool key_added_; |
| }; |
| |
| #endif // TOOLS_GN_FUNCTIONS_H_ |