| // 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 kExpandDirectory[]; | |
| extern const char kExpandDirectory_HelpShort[]; | |
| extern const char kExpandDirectory_Help[]; | |
| Value RunExpandDirectory(Scope* scope, | |
| const FunctionCallNode* function, | |
| const std::vector<Value>& args, | |
| Err* err); | |
| extern const char kFilterExclude[]; | |
| extern const char kFilterExclude_HelpShort[]; | |
| extern const char kFilterExclude_Help[]; | |
| Value RunFilterExclude(Scope* scope, | |
| const FunctionCallNode* function, | |
| const std::vector<Value>& args, | |
| Err* err); | |
| extern const char kFilterInclude[]; | |
| extern const char kFilterInclude_HelpShort[]; | |
| extern const char kFilterInclude_Help[]; | |
| Value RunFilterInclude(Scope* scope, | |
| const FunctionCallNode* function, | |
| const std::vector<Value>& args, | |
| Err* err); | |
| extern const char kFilterLabelsInclude[]; | |
| extern const char kFilterLabelsInclude_HelpShort[]; | |
| extern const char kFilterLabelsInclude_Help[]; | |
| Value RunFilterLabelsInclude(Scope* scope, | |
| const FunctionCallNode* function, | |
| const std::vector<Value>& args, | |
| Err* err); | |
| extern const char kFilterLabelsExclude[]; | |
| extern const char kFilterLabelsExclude_HelpShort[]; | |
| extern const char kFilterLabelsExclude_Help[]; | |
| Value RunFilterLabelsExclude(Scope* scope, | |
| const FunctionCallNode* function, | |
| const std::vector<Value>& args, | |
| 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 kLabelMatches[]; | |
| extern const char kLabelMatches_HelpShort[]; | |
| extern const char kLabelMatches_Help[]; | |
| Value RunLabelMatches(Scope* scope, | |
| const FunctionCallNode* function, | |
| const std::vector<Value>& args, | |
| Err* err); | |
| extern const char kLen[]; | |
| extern const char kLen_HelpShort[]; | |
| extern const char kLen_Help[]; | |
| Value RunLen(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 kPathExists[]; | |
| extern const char kPathExists_HelpShort[]; | |
| extern const char kPathExists_Help[]; | |
| Value RunPathExists(Scope* scope, | |
| const FunctionCallNode* function, | |
| const std::vector<Value>& args, | |
| 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 kRustProcMacro[]; | |
| extern const char kRustProcMacro_HelpShort[]; | |
| extern const char kRustProcMacro_Help[]; | |
| Value RunRustProcMacro(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 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 nonexistent keys which will cause assertions. | |
| bool key_added_; | |
| }; | |
| #endif // TOOLS_GN_FUNCTIONS_H_ |