// 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 #include #include #include "base/strings/string_piece.h" 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. typedef Value (*SelfEvaluatingArgsFunction)(Scope* scope, const FunctionCallNode* function, const ListNode* args_list, Err* err); // This type of function invocation takes a block node that it will execute. typedef Value (*GenericBlockFunction)(Scope* scope, const FunctionCallNode* function, const std::vector& 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. typedef Value(*ExecutedBlockFunction)(const FunctionCallNode* function, const std::vector& args, Scope* block_scope, Err* err); // This type of function does not take a block. It just has arguments. typedef Value (*NoBlockFunction)(Scope* scope, const FunctionCallNode* function, const std::vector& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& args, 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& 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& 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& 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& 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& 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& 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& 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& args, 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& 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& 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& 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& 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& 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& args, BlockNode* block, 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& 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& 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& 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& 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& 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; }; typedef std::map FunctionInfoMap; // 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& 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& 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_