src/functioncreator.cpp
/*!
 * \fn Function create(FunctionBlueprint& blueprint, const std::shared_ptr<ast::FunctionDeclaration>& fdecl, std::vector<Attribute>& attrs)
 * \brief creates a function from a blueprint
 * \param the blueprint
 * \param the function declaration
 * \param the attributes
 * 
 * This function creates a function from the blueprint.
 * The function should not be added to its future parent.
 * 
 * The default implementation does not use the attributes and supports a null function declaration.
 */


This function creates a function from the blueprint.
The function should not be added to its future parent.

The default implementation does not use the attributes and supports a null function declaration.
This function creates a function from the blueprint . The function should not be added to its future parent . The default implementation does not use the attributes and supports a null function declaration .
Function FunctionCreator::create(FunctionBlueprint& blueprint, const std::shared_ptr<ast::FunctionDecl>& fdecl, std::vector<Attribute>& )
{
  if (fdecl && (fdecl->body || fdecl->defaultKeyword.isValid()))
  {
    if (!blueprint.body_)
      blueprint.body_ = compile_later();
  }
  if (blueprint.name_.kind() == SymbolKind::Function)
  {
    auto impl = std::make_shared<RegularFunctionImpl>(blueprint.name_.string(), std::move(blueprint.prototype_), blueprint.engine(), blueprint.flags_);
    generic_fill(impl, blueprint);
    Function ret{ impl };
    return ret;
  }
  else if (blueprint.name_.kind() == SymbolKind::Operator)
  {
    OperatorName operation = blueprint.name_.operatorName();
    if (operation == OperatorName::FunctionCallOperator)
    {
      auto impl = std::make_shared<FunctionCallOperatorImpl>(OperatorName::FunctionCallOperator, std::move(blueprint.prototype_), blueprint.engine(), blueprint.flags_);
      generic_fill(impl, blueprint);
      Operator ret{ impl };
      return ret;
    }
    else
    {
      std::shared_ptr<OperatorImpl> impl;
      if (Operator::isBinary(operation))
        impl = std::make_shared<BinaryOperatorImpl>(operation, blueprint.prototype_, blueprint.engine(), blueprint.flags_);
      else
        impl = std::make_shared<UnaryOperatorImpl>(operation, blueprint.prototype_, blueprint.engine(), blueprint.flags_);
      generic_fill(impl, blueprint);
      return Operator{ impl };
    }
  }
  else if (blueprint.name_.kind() == SymbolKind::Cast)
  {
    auto impl = std::make_shared<CastImpl>(blueprint.prototype_, blueprint.engine(), blueprint.flags_);
    generic_fill(impl, blueprint);
    Function ret{ impl };
    return ret;
  }
  else if (blueprint.name_.kind() == SymbolKind::Constructor)
  {
    auto impl = std::make_shared<ConstructorImpl>(blueprint.prototype_, blueprint.engine(), blueprint.flags_);
    generic_fill(impl, blueprint);
    Function ret{ impl };
    return ret;
  }
  else if (blueprint.name_.kind() == SymbolKind::Destructor)
  {
    auto impl = std::make_shared<DestructorImpl>(blueprint.prototype_, blueprint.engine(), blueprint.flags_);
    generic_fill(impl, blueprint);
    Function ret{ impl };
    return ret;
  }
  else if (blueprint.name_.kind() == SymbolKind::LiteralOperator)
  {
    auto impl = std::make_shared<LiteralOperatorImpl>(blueprint.name_.string(), blueprint.prototype_, blueprint.engine(), blueprint.flags_);
    generic_fill(impl, blueprint);
    Function ret{ impl };
    return ret;
  }
  else
  {
    assert(false);
    return {};
  }
}
Function FunctionCreator :: create ( FunctionBlueprint & blueprint , const std :: shared_ptr < ast :: FunctionDecl > & fdecl , std :: vector < Attribute > & ) { if ( fdecl && ( fdecl -> body || fdecl -> defaultKeyword . isValid ( ) ) ) { if ( ! blueprint . body_ ) blueprint . body_ = compile_later ( ) ; } if ( blueprint . name_ . kind ( ) == SymbolKind :: Function ) { auto impl = std :: make_shared < RegularFunctionImpl > ( blueprint . name_ . string ( ) , std :: move ( blueprint . prototype_ ) , blueprint . engine ( ) , blueprint . flags_ ) ; generic_fill ( impl , blueprint ) ; Function ret { impl } ; return ret ; } else if ( blueprint . name_ . kind ( ) == SymbolKind :: Operator ) { OperatorName operation = blueprint . name_ . operatorName ( ) ; if ( operation == OperatorName :: FunctionCallOperator ) { auto impl = std :: make_shared < FunctionCallOperatorImpl > ( OperatorName :: FunctionCallOperator , std :: move ( blueprint . prototype_ ) , blueprint . engine ( ) , blueprint . flags_ ) ; generic_fill ( impl , blueprint ) ; Operator ret { impl } ; return ret ; } else { std :: shared_ptr < OperatorImpl > impl ; if ( Operator :: isBinary ( operation ) ) impl = std :: make_shared < BinaryOperatorImpl > ( operation , blueprint . prototype_ , blueprint . engine ( ) , blueprint . flags_ ) ; else impl = std :: make_shared < UnaryOperatorImpl > ( operation , blueprint . prototype_ , blueprint . engine ( ) , blueprint . flags_ ) ; generic_fill ( impl , blueprint ) ; return Operator { impl } ; } } else if ( blueprint . name_ . kind ( ) == SymbolKind :: Cast ) { auto impl = std :: make_shared < CastImpl > ( blueprint . prototype_ , blueprint . engine ( ) , blueprint . flags_ ) ; generic_fill ( impl , blueprint ) ; Function ret { impl } ; return ret ; } else if ( blueprint . name_ . kind ( ) == SymbolKind :: Constructor ) { auto impl = std :: make_shared < ConstructorImpl > ( blueprint . prototype_ , blueprint . engine ( ) , blueprint . flags_ ) ; generic_fill ( impl , blueprint ) ; Function ret { impl } ; return ret ; } else if ( blueprint . name_ . kind ( ) == SymbolKind :: Destructor ) { auto impl = std :: make_shared < DestructorImpl > ( blueprint . prototype_ , blueprint . engine ( ) , blueprint . flags_ ) ; generic_fill ( impl , blueprint ) ; Function ret { impl } ; return ret ; } else if ( blueprint . name_ . kind ( ) == SymbolKind :: LiteralOperator ) { auto impl = std :: make_shared < LiteralOperatorImpl > ( blueprint . name_ . string ( ) , blueprint . prototype_ , blueprint . engine ( ) , blueprint . flags_ ) ; generic_fill ( impl , blueprint ) ; Function ret { impl } ; return ret ; } else { assert ( false ) ; return { } ; } }
\fn Function create(FunctionBlueprint& blueprint, const std::shared_ptr<ast::FunctionDeclaration>& fdecl, std::vector<Attribute>& attrs)
 \brief creates a function from a blueprint
 \param the blueprint
 \param the function declaration
 \param the attributes
\ fn Function create ( FunctionBlueprint& blueprint const std :: shared_ptr<ast :: FunctionDeclaration > & fdecl std :: vector<Attribute > & attrs ) \ brief creates a function from a blueprint \ param the blueprint \ param the function declaration \ param the attributes
/* attrs */