00001 #include "stdafx.h" 00002 00003 #include "method.h" 00004 #include "Any.h" 00005 #include "CodeGen.h" 00006 00007 static const std::string orn = "//********************************************************************************\n"; 00008 /*const*/ extern int h_ind; 00009 /*const*/ extern int s_ind; 00010 00011 bool MethodLexicographicSort::operator()( const Method& op1, const Method& op2) const 00012 { 00013 const std::string s1 = op1.m_signature; 00014 const std::string s2 = op2.m_signature; 00015 return ( s1.compare(s2) < 0); 00016 } 00017 00018 00019 Method::Method() 00020 : m_virtual( true) 00021 , m_static( false) 00022 , m_template( false) 00023 , m_returnValue() 00024 , m_signature() 00025 , m_implementation() 00026 , m_comment() 00027 , m_container(0) 00028 { } 00029 00030 00031 std::string Method::getHeader() 00032 { 00033 if ( m_template) 00034 { 00035 return CodeGen::indent(h_ind) + orn + 00036 CodeGen::indent(h_ind) + "// " + m_comment + "\n" + 00037 CodeGen::indent(h_ind) + orn + 00038 m_returnValue + CodeGen::indent(2) + m_signature + "\n" + m_implementation; 00039 } 00040 00041 std::string ret_val = (m_virtual?"virtual ":"") + m_returnValue; 00042 int fill_size = ret_val.size() < 20? 20 - ret_val.size(): ret_val.size() < 40? 40-ret_val.size(): ret_val.size() < 50? 50-ret_val.size():1; 00043 return CodeGen::indent(h_ind) + ret_val + CodeGen::fill( fill_size) + m_signature + ";"; 00044 } 00045 00046 00047 std::string Method::getSource() 00048 { 00049 if ( m_template || m_implementation.empty()) // templates or dummies like init/finalize 00050 return ""; 00051 00052 ASSERT( m_container); 00053 return 00054 CodeGen::indent(s_ind) + orn + 00055 CodeGen::indent(s_ind) + "// " + m_comment + "\n" + 00056 CodeGen::indent(s_ind) + orn + 00057 CodeGen::indent(s_ind) + m_returnValue + " " + m_container->getValidNmspc() + Any::NamespaceDelimiter_str + m_container->getValidNameImpl() + "::" + m_signature + "\n" + 00058 m_implementation; 00059 } 00060 00061 00062 std::string Method::getExposed( const std::string& repl_cont) 00063 { 00064 // the using directive needs the immediate parent to be specified before the '::' 00065 // so grandparent's name is not allowed 00066 // i.e: 00067 // A<>-----r 00068 // /|\ 00069 // | 00070 // B<>-----p 00071 // /.\ 00072 // | 00073 // C (implementation inheritance between B and C) 00074 // 00075 // in such cases C inherits privately from A thus hides to its users the 00076 // methods inherited like: getr() and getp() 00077 // these methods needed to be exposed by 00078 // using B::getp; 00079 // using A::getr; directives 00080 // but the latter i not allowed (A is granparent of C), so 'using B::getr;' has to be used 00081 // this is valid since B does have getr() method (inherited) 00082 ASSERT( m_container); 00083 return CodeGen::indent(h_ind) + "using " + (repl_cont.empty()?m_container->getValidNameImpl():repl_cont) + "::" + m_signature.substr(0, m_signature.find('(')) + ";"; 00084 } 00085 00086 00087 std::string Method::getHidden() 00088 { 00089 return CodeGen::indent(h_ind) + (m_template?"":"virtual ") + m_returnValue + " " + m_signature + 00090 " { throw std::string(\"Interface inherited kind. \" + getName() + \" doesn't have " + m_signature + " method.\"); }"; 00091 00092 } 00093 00094 00095 Method::operator bool() 00096 { 00097 if ( m_container != 0) 00098 return true; 00099 else 00100 return false; 00101 } 00102