[mapguide-commits] r7628 - sandbox/jng/node/Oem/SWIGEx/Source/Modules
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Tue Jun 18 09:29:43 PDT 2013
Author: jng
Date: 2013-06-18 09:29:43 -0700 (Tue, 18 Jun 2013)
New Revision: 7628
Modified:
sandbox/jng/node/Oem/SWIGEx/Source/Modules/nodejs.cxx
Log:
This submission includes:
* Fragment and exception handling code generation with RAII semantics allowing for formatted codegen in an intuitive fashion.
* Refactor the function argument call checking and marshalling to be re-usable for constructor calls
* Implement codegen for "delete_" methods
Modified: sandbox/jng/node/Oem/SWIGEx/Source/Modules/nodejs.cxx
===================================================================
--- sandbox/jng/node/Oem/SWIGEx/Source/Modules/nodejs.cxx 2013-06-18 14:37:13 UTC (rev 7627)
+++ sandbox/jng/node/Oem/SWIGEx/Source/Modules/nodejs.cxx 2013-06-18 16:29:43 UTC (rev 7628)
@@ -23,6 +23,96 @@
~Indenter() { m_level--; }
};
+class FragmentWriter
+{
+private:
+ std::string& m_fragment;
+ int& m_indent;
+
+public:
+ FragmentWriter(int& indentLevel, std::string& fragment) : m_indent(indentLevel), m_fragment(fragment)
+ {
+ }
+
+ int& indent() { return m_indent; }
+
+ void writeTabs()
+ {
+ if (m_indent > 0)
+ {
+ for (int i = 0; i < m_indent; i++)
+ {
+ m_fragment += "\t";
+ }
+ }
+ }
+
+ void writeToFragment(String* str, bool bDelete = true)
+ {
+ writeTabs();
+ m_fragment += Char(str);
+ if (bDelete)
+ Delete(str);
+ }
+
+ void writeToFragment(const std::string& str)
+ {
+ writeTabs();
+ m_fragment += str;
+ }
+
+ void writeToFragment(const char* str)
+ {
+ writeTabs();
+ m_fragment += str;
+ }
+};
+
+class ExceptionCodeWriter
+{
+private:
+ FragmentWriter& m_frag;
+ std::string m_try_macro;
+ std::string m_catch_macro;
+ std::string m_methodName;
+ bool m_bIncludeRawPointerCleanup;
+
+public:
+ ExceptionCodeWriter(FragmentWriter& frag,
+ std::string methodName,
+ std::string tryMacro = "MG_TRY",
+ std::string catchMacro = "MG_CATCH",
+ bool bIncludeRawPointerCleanup = false)
+ : m_frag(frag),
+ m_try_macro(tryMacro),
+ m_catch_macro(catchMacro),
+ m_methodName(methodName),
+ m_bIncludeRawPointerCleanup(bIncludeRawPointerCleanup)
+ {
+ m_frag.writeToFragment(NewStringf("%s()\n", m_try_macro.c_str()));
+ }
+
+ ~ExceptionCodeWriter()
+ {
+ m_frag.writeToFragment(NewStringf("%s(L\"%s\")\n", m_catch_macro.c_str(), m_methodName.c_str()));
+ m_frag.writeToFragment("if (mgException != NULL)\n");
+ m_frag.writeToFragment("{\n");
+ {
+ Indenter ind2(m_frag.indent());
+ m_frag.writeToFragment("//NOTE: Unlike previous iterations of the MapGuide API, MgException::GetDetails() finally gives us *everything*\n");
+ m_frag.writeToFragment("STRING details = mgException->GetDetails();\n");
+ m_frag.writeToFragment("std::string mbDetails = MgUtil::WideCharToMultiByte(details);\n");
+ m_frag.writeToFragment("v8::Local<v8::Value> v8ex = v8::Exception::Error(v8::String::New(mbDetails.c_str()));\n");
+ m_frag.writeToFragment("//Release our MgException before throwing the v8 one\n");
+ m_frag.writeToFragment("mgException = NULL;\n");
+ if (m_bIncludeRawPointerCleanup)
+ m_frag.writeToFragment(NewStringf("if (%s) { ((MgDisposable*)%s)->Release(); %s = NULL; }\n", WRAPPED_PTR_VAR, WRAPPED_PTR_VAR, WRAPPED_PTR_VAR));
+ m_frag.writeToFragment("return v8::ThrowException(v8ex);\n");
+ }
+ m_frag.writeToFragment("}\n");
+ }
+};
+
class NODEJS : public Language
{
private:
@@ -186,138 +276,82 @@
String* dtorPrefix = NewString("delete_");
if (Strstr(name, entry))
{
- writeToFile(NewStringf("//Global Function: %s\n", name));
- writeToFile(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& %s) {\n", name, ARGS_VAR));
+ std::string globalFuncFragment;
+ FragmentWriter cls(m_indentationLevels, globalFuncFragment);
+ cls.writeToFragment(NewStringf("//Global Function: %s\n", name));
+ std::string proxyFuncName;
+ setProxyClassName(name, proxyFuncName);
+ cls.writeToFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& %s) {\n", proxyFuncName.c_str(), ARGS_VAR));
{
Indenter ind(m_indentationLevels);
- //writeToFile("v8::HandleScope scope;\n");
- //writeToFile("return scope.Close();\n");
- writeToFile("return v8::Undefined();\n");
+ {
+ ExceptionCodeWriter writer(cls, proxyFuncName);
+ std::string funcCall;
+ std::string cleanup;
+ getFunctionArgumentAssignmentCode(parms, cls, funcCall);
+ cls.writeToFragment(NewStringf("%s(%s);\n", name, funcCall.c_str()));
+ }
+ cls.writeToFragment("return v8::Undefined();\n");
}
- writeToFile("}\n");
+ cls.writeToFragment("}\n");
+
+ m_classMethodDecls.push_back(globalFuncFragment);
}
else if (Strstr(name, ctorPrefix))
{
+ std::string ctorFragment;
+ FragmentWriter ctor(m_indentationLevels, ctorFragment);
String* ovName = getOverloadedName(n);
- writeToCurrentClassFragment(NewStringf("//ctor Function Wrapper: %s\n", name));
- writeToCurrentClassFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& %s) {\n", ovName, ARGS_VAR));
+ ctor.writeToFragment(NewStringf("//ctor Function Wrapper: %s\n", name));
+
+ std::string mbName = Char(name);
+ //Strip the new_ prefix
+ std::string ctorName = mbName.substr(4);
+ std::string proxyClsName;
+ setProxyClassName(ctorName.c_str(), proxyClsName);
+
+ ctor.writeToFragment(NewStringf("static %s* %s(const v8::Arguments& %s) {\n", ctorName.c_str(), ovName, ARGS_VAR));
{
Indenter ind(m_indentationLevels);
- //writeToCurrentClassFragment("v8::HandleScope scope;\n");
- //writeToCurrentClassFragment("return scope.Close();\n");
- writeToCurrentClassFragment("return v8::Undefined();\n");
+
+ std::string funcCall;
+ getFunctionArgumentAssignmentCode(parms, ctor, funcCall, false);
+ ctor.writeToFragment(NewStringf("Ptr<%s> retVal;\n", ctorName.c_str()));
+ ctor.writeToFragment(NewStringf("retVal = new %s(%s);\n", ctorName.c_str(), funcCall.c_str()));
+ ctor.writeToFragment("return retVal.Detach();\n");
}
- writeToCurrentClassFragment("}\n");
+ ctor.writeToFragment("}\n");
+ m_classMethodDecls.push_back(ctorFragment);
}
else if (Strstr(name, dtorPrefix))
{
- writeToCurrentClassFragment(NewStringf("//dtor Function Wrapper: %s\n", name));
- writeToCurrentClassFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& %s) {\n", name, ARGS_VAR));
+ std::string dtorFragment;
+ FragmentWriter dtor(m_indentationLevels, dtorFragment);
+ dtor.writeToFragment(NewStringf("//dtor Function Wrapper: %s\n", name));
+ dtor.writeToFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& %s) {\n", name, ARGS_VAR));
{
Indenter ind(m_indentationLevels);
- //writeToCurrentClassFragment("v8::HandleScope scope;\n");
- //writeToCurrentClassFragment("return scope.Close();\n");
- writeToCurrentClassFragment("return v8::Undefined();\n");
+
+ std::string funcCall;
+ getFunctionArgumentAssignmentCode(parms, dtor, funcCall);
+
+ //TODO: Should check if node/v8 allows this. This is theoretical atm
+ //
+ //There'll only be one argument, the pointer to release
+ //Argument marshalling will create a Ptr<> of the internal pointer
+ //and a Proxy pointer that wraps another Ptr<> of the same pointer
+ //
+ //Thus deleting the proxy pointer will trigger the internal Ptr<> to
+ //release it
+ dtor.writeToFragment("delete proxyArg0;\n");
}
- writeToCurrentClassFragment("}\n");
+ dtor.writeToFragment("}\n");
+ m_classMethodDecls.push_back(dtorFragment);
}
Language::functionWrapper(n);
return SWIG_OK;
}
- void writeTabsToCurrentClassSetupFragment()
- {
- if (m_indentationLevels > 0)
- {
- for (int i = 0; i < m_indentationLevels; i++)
- {
- m_currentClassSetupFragment += "\t";
- }
- }
- }
-
- void writeToCurrentClassSetupFragment(String* str, bool bDelete = true)
- {
- writeTabsToCurrentClassSetupFragment();
- m_currentClassSetupFragment += Char(str);
- if (bDelete)
- Delete(str);
- }
-
- void writeToCurrentClassSetupFragment(const std::string& str)
- {
- writeTabsToCurrentClassSetupFragment();
- m_currentClassSetupFragment += str;
- }
-
- void writeToCurrentClassSetupFragment(const char* str)
- {
- writeTabsToCurrentClassSetupFragment();
- m_currentClassSetupFragment += str;
- }
-
- void writeTabsToCurrentMethodFragment()
- {
- if (m_indentationLevels > 0)
- {
- for (int i = 0; i < m_indentationLevels; i++)
- {
- m_currentMethodFragment += "\t";
- }
- }
- }
-
- void writeToCurrentMethodFragment(String* str, bool bDelete = true)
- {
- writeTabsToCurrentMethodFragment();
- m_currentMethodFragment += Char(str);
- if (bDelete)
- Delete(str);
- }
-
- void writeToCurrentMethodFragment(const std::string& str)
- {
- writeTabsToCurrentMethodFragment();
- m_currentMethodFragment += str;
- }
-
- void writeToCurrentMethodFragment(const char* str)
- {
- writeTabsToCurrentMethodFragment();
- m_currentMethodFragment += str;
- }
-
- void writeTabsToCurrentClassFragment()
- {
- if (m_indentationLevels > 0)
- {
- for (int i = 0; i < m_indentationLevels; i++)
- {
- m_currentFragment += "\t";
- }
- }
- }
-
- void writeToCurrentClassFragment(String* str, bool bDelete = true)
- {
- writeTabsToCurrentClassFragment();
- m_currentFragment += Char(str);
- if (bDelete)
- Delete(str);
- }
-
- void writeToCurrentClassFragment(const std::string& str)
- {
- writeTabsToCurrentClassFragment();
- m_currentFragment += str;
- }
-
- void writeToCurrentClassFragment(const char* str)
- {
- writeTabsToCurrentClassFragment();
- m_currentFragment += str;
- }
-
void writeTabsToFile()
{
if (m_indentationLevels > 0)
@@ -349,6 +383,12 @@
Printf(m_fOutputFile, str);
}
+ static void setProxyClassName(const char* clsName, std::string& sOut)
+ {
+ sOut = "Proxy";
+ sOut += clsName;
+ }
+
static void setProxyClassName(String* clsName, std::string& sOut)
{
sOut = "Proxy";
@@ -372,12 +412,15 @@
m_currentExportFragment = std::string();
m_currentClassName = NewString(Getattr(n,"sym:name"));
+ FragmentWriter cls(m_indentationLevels, m_currentFragment);
+ FragmentWriter clsSetup(m_indentationLevels, m_currentClassSetupFragment);
+
//NOTE: We currently don't export MgException classes, they're unusable in JavaScript, any exceptions that
//any MapGuide API will throw will be caught by this node.js extension and re-thrown as a JavaScript
//Error object.
if (!Strstr(m_currentClassName, "Exception"))
{
- writeToCurrentClassFragment(NewStringf("//Node.js wrapper for class: %s\n", m_currentClassName));
+ cls.writeToFragment(NewStringf("//Node.js wrapper for class: %s\n", m_currentClassName));
std::string proxyClsName;
setProxyClassName(m_currentClassName, proxyClsName);
@@ -393,19 +436,19 @@
//Export call
m_currentExportFragment += proxyClsName;
- m_currentExportFragment += "_Export(";
+ m_currentExportFragment += "::Export(";
m_currentExportFragment += EXPORTS_VAR;
m_currentExportFragment += ");";
m_currentInheritFragment += proxyClsName;
- m_currentInheritFragment += "_ApplyInheritanceChain(";
+ m_currentInheritFragment += "::ApplyInheritanceChain(";
m_currentInheritFragment += EXPORTS_VAR;
m_currentInheritFragment += ");";
//Unmanaged pointer member
- writeToCurrentClassFragment(clsHead);
- writeToCurrentClassFragment("{\n");
- writeToCurrentClassFragment("protected:\n");
+ cls.writeToFragment(clsHead);
+ cls.writeToFragment("{\n");
+ cls.writeToFragment("protected:\n");
bool isMgObject = isCurrentClassMgObject();
@@ -415,7 +458,7 @@
std::string ptrDecl;
ptrDecl += Char(m_currentClassName);
ptrDecl += "* m_ptr;\n";
- writeToCurrentClassFragment(ptrDecl);
+ cls.writeToFragment(ptrDecl);
}
else
{
@@ -423,9 +466,9 @@
std::string ptrDecl = "Ptr<";
ptrDecl += Char(m_currentClassName);
ptrDecl += "> m_ptr;\n";
- writeToCurrentClassFragment(ptrDecl);
+ cls.writeToFragment(ptrDecl);
}
- writeToCurrentClassFragment("public:\n");
+ cls.writeToFragment("public:\n");
std::string ctorDecl;
ctorDecl += proxyClsName;
ctorDecl += "(";
@@ -434,13 +477,13 @@
//ctor
{
Indenter ind(m_indentationLevels);
- writeToCurrentClassFragment(ctorDecl);
- writeToCurrentClassFragment("{\n");
+ cls.writeToFragment(ctorDecl);
+ cls.writeToFragment("{\n");
if (isMgObject) //Anything inheriting from MgObject will be MgDisposable
- writeToCurrentClassFragment("\tm_ptr = SAFE_ADDREF((MgDisposable*)ptr);\n");
+ cls.writeToFragment("\tm_ptr = SAFE_ADDREF((MgDisposable*)ptr);\n");
else
- writeToCurrentClassFragment("\tm_ptr = SAFE_ADDREF(ptr);\n");
- writeToCurrentClassFragment("}\n");
+ cls.writeToFragment("\tm_ptr = SAFE_ADDREF(ptr);\n");
+ cls.writeToFragment("}\n");
}
std::string dtorDecl;
dtorDecl += "~";
@@ -449,15 +492,22 @@
//dtor
{
Indenter ind(m_indentationLevels);
- writeToCurrentClassFragment(dtorDecl);
- writeToCurrentClassFragment("{\n");
+ cls.writeToFragment(dtorDecl);
+ cls.writeToFragment("{\n");
if (isMgObject) //Anything inheriting from MgObject will be MgDisposable
- writeToCurrentClassFragment("\t((MgDisposable*)m_ptr)->Release();\n");
+ cls.writeToFragment("\t((MgDisposable*)m_ptr)->Release();\n");
else
- writeToCurrentClassFragment("\tm_ptr = NULL;\n");
- writeToCurrentClassFragment("}\n");
+ cls.writeToFragment("\tm_ptr = NULL;\n");
+ cls.writeToFragment("}\n");
}
+ //Stubs to be implemented further down
+ {
+ Indenter ind(m_indentationLevels);
+ cls.writeToFragment("static void Export(v8::Handle<v8::Object> exports);\n");
+ cls.writeToFragment("static void ApplyInheritanceChain(v8::Handle<v8::Object> exports);\n");
+ }
+
//Class body
{
Indenter ind(m_indentationLevels);
@@ -468,32 +518,35 @@
{
Indenter ind(m_indentationLevels);
if (isMgObject)
- writeToCurrentClassFragment(NewStringf("%s* GetInternalPointer() { return SAFE_ADDREF((MgDisposable*)m_ptr); }\n", m_currentClassName));
+ cls.writeToFragment(NewStringf("%s* GetInternalPointer() { return SAFE_ADDREF((MgDisposable*)m_ptr); }\n", m_currentClassName));
else
- writeToCurrentClassFragment(NewStringf("%s* GetInternalPointer() { return SAFE_ADDREF(m_ptr.p); }\n", m_currentClassName));
+ cls.writeToFragment(NewStringf("%s* GetInternalPointer() { return SAFE_ADDREF(m_ptr.p); }\n", m_currentClassName));
}
+ cls.writeToFragment("private:\n");
//Proxy Constructor
{
Indenter ind(m_indentationLevels);
- writeToCurrentClassFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& %s) {\n", CLASS_PROXY_CTOR_NAME, ARGS_VAR));
+ cls.writeToFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& %s) {\n", CLASS_PROXY_CTOR_NAME, ARGS_VAR));
{
Indenter ind2(m_indentationLevels);
- writeToCurrentClassFragment("//TODO: Parse arguments and determine which actual native constructor to invoke\n");
- writeToCurrentClassFragment("return v8::Undefined();\n");
+ cls.writeToFragment("//TODO: Parse arguments and determine which actual native constructor to invoke\n");
+ cls.writeToFragment("return v8::Undefined();\n");
}
- writeToCurrentClassFragment("}\n");
+ cls.writeToFragment("}\n");
}
//node/v8 export function
{
Indenter ind(m_indentationLevels);
- writeToCurrentClassSetupFragment(NewStringf("static void %s_Export(v8::Handle<v8::Object> %s)\n", proxyClsName.c_str(), EXPORTS_VAR));
- writeToCurrentClassSetupFragment("{\n");
+ clsSetup.writeToFragment(NewStringf("void %s::Export(v8::Handle<v8::Object> %s)\n", proxyClsName.c_str(), EXPORTS_VAR));
+ clsSetup.writeToFragment("{\n");
{
Indenter ind2(m_indentationLevels);
- writeToCurrentClassSetupFragment(NewStringf("v8::Local<v8::FunctionTemplate> %s = v8::FunctionTemplate::New(%s::%s);\n", CLASS_EXPORT_VAR, proxyClsName.c_str(), CLASS_PROXY_CTOR_NAME));
- writeToCurrentClassSetupFragment(NewStringf("%s->SetClassName(v8::String::NewSymbol(\"%s\"));\n", CLASS_EXPORT_VAR, m_currentClassName));
+ clsSetup.writeToFragment(NewStringf("v8::Local<v8::FunctionTemplate> %s = v8::FunctionTemplate::New(%s::%s);\n", CLASS_EXPORT_VAR, proxyClsName.c_str(), CLASS_PROXY_CTOR_NAME));
+ clsSetup.writeToFragment(NewStringf("%s->SetClassName(v8::String::NewSymbol(\"%s\"));\n", CLASS_EXPORT_VAR, m_currentClassName));
+ clsSetup.writeToFragment("//For the internal pointer\n");
+ clsSetup.writeToFragment(NewStringf("%s->InstanceTemplate()->SetInternalFieldCount(1);\n", CLASS_EXPORT_VAR));
std::string ctorReg = "v8::Persistent<v8::Function> constructor = v8::Persistent<v8::Function>::New(";
ctorReg += CLASS_EXPORT_VAR;
@@ -510,26 +563,26 @@
for (std::vector<std::string>::iterator it = m_classMemberExportCalls.begin(); it != m_classMemberExportCalls.end(); it++)
{
- writeToCurrentClassSetupFragment((*it));
- writeToCurrentClassSetupFragment("\n");
+ clsSetup.writeToFragment((*it));
+ clsSetup.writeToFragment("\n");
}
}
- writeToCurrentClassSetupFragment("}\n");
+ clsSetup.writeToFragment("}\n");
}
//node/v8 inheritance hook
{
Indenter ind(m_indentationLevels);
- writeToCurrentClassSetupFragment(NewStringf("static void %s_ApplyInheritanceChain(v8::Handle<v8::Object> %s)\n", proxyClsName.c_str(), EXPORTS_VAR));
- writeToCurrentClassSetupFragment("{\n");
+ clsSetup.writeToFragment(NewStringf("void %s::ApplyInheritanceChain(v8::Handle<v8::Object> %s)\n", proxyClsName.c_str(), EXPORTS_VAR));
+ clsSetup.writeToFragment("{\n");
{
Indenter ind2(m_indentationLevels);
- writeToCurrentClassSetupFragment("//TODO: Apply prototype inheritance chain\n");
+ clsSetup.writeToFragment("//TODO: Apply prototype inheritance chain\n");
}
- writeToCurrentClassSetupFragment("}\n");
+ clsSetup.writeToFragment("}\n");
}
- writeToCurrentClassFragment("};");
+ cls.writeToFragment("};");
Delete(m_currentClassName);
m_currentClassName = NULL;
@@ -546,7 +599,8 @@
virtual int memberconstantHandler(Node* n)
{
String* name = Getattr(n, "sym:name");
- writeToCurrentClassFragment(NewStringf("//\tMember Constant: %s::%s\n", m_currentClassName, name));
+ FragmentWriter frag(m_indentationLevels, m_currentFragment);
+ frag.writeToFragment(NewStringf("//\tMember Constant: %s::%s\n", m_currentClassName, name));
String* swExpCall = NewStringf("//TODO: Export constant %s::%s", m_currentClassName, name);
std::string expCall = Char(swExpCall);
Delete(swExpCall);
@@ -571,29 +625,30 @@
m_currentMethodFragment = std::string();
+ FragmentWriter meth(m_indentationLevels, m_currentMethodFragment);
//Proxy method is encoded as ClassName_SwigQualifiedMethodName
- writeToCurrentMethodFragment(NewStringf("//\tMember Function: %s::%s\n", m_currentClassName, overloaded_name));
- writeToCurrentMethodFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& %s) {\n", overloaded_name_qualified, ARGS_VAR));
+ meth.writeToFragment(NewStringf("//\tMember Function: %s::%s\n", m_currentClassName, overloaded_name));
+ meth.writeToFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& %s) {\n", overloaded_name_qualified, ARGS_VAR));
{
Indenter ind(m_indentationLevels);
std::string wrappedPtrCall;
- writeToCurrentMethodFragment(NewStringf("//Return type - %s (pointer? %s)\n", retType, (isMgPointer ? "true" : "false")));
+ meth.writeToFragment(NewStringf("//Return type - %s (pointer? %s)\n", retType, (isMgPointer ? "true" : "false")));
if (isVoid)
{
- writeToCurrentMethodFragment("//Function is void and does not return a value\n");
+ meth.writeToFragment("//Function is void and does not return a value\n");
}
else
{
if (isMgPointer)
{
- writeToCurrentMethodFragment(NewStringf("Ptr<%s> %s;\n", retTypeUnprefixed, FUNC_RET_VAR));
+ meth.writeToFragment(NewStringf("Ptr<%s> %s;\n", retTypeUnprefixed, FUNC_RET_VAR));
}
else
{
- writeToCurrentMethodFragment(NewStringf("%s %s;\n", retType, FUNC_RET_VAR));
+ meth.writeToFragment(NewStringf("%s %s;\n", retType, FUNC_RET_VAR));
}
}
@@ -606,73 +661,64 @@
wrappedPtrCall += "->";
if (isCurrentClassMgObject())
- writeToCurrentMethodFragment(NewStringf("%s* %s = NULL;\n", m_currentClassName, WRAPPED_PTR_VAR));
+ meth.writeToFragment(NewStringf("%s* %s = NULL;\n", m_currentClassName, WRAPPED_PTR_VAR));
else
- writeToCurrentMethodFragment(NewStringf("Ptr<%s> %s;\n", m_currentClassName, WRAPPED_PTR_VAR));
- writeToCurrentMethodFragment("MG_TRY()\n");
+ meth.writeToFragment(NewStringf("Ptr<%s> %s;\n", m_currentClassName, WRAPPED_PTR_VAR));
- if (parms)
+
{
- std::string funcCallArgsStr;
- getFunctionArgumentAssignmentCode(parms, funcCallArgsStr);
- wrappedPtrCall += Char(name);
- wrappedPtrCall += "(";
- wrappedPtrCall += funcCallArgsStr;
- wrappedPtrCall += ");\n";
- }
- else
- {
- writeToCurrentMethodFragment("//Function has no arguments\n");
- wrappedPtrCall += Char(name);
- wrappedPtrCall += "();\n";
- }
-
- writeToCurrentMethodFragment(NewStringf("%s* proxy = node::ObjectWrap::Unwrap<%s>(%s.This());\n", proxyClsName.c_str(), proxyClsName.c_str(), ARGS_VAR));
- writeToCurrentMethodFragment(NewStringf("%s = proxy->GetInternalPointer();\n", WRAPPED_PTR_VAR));
-
- //Here's the actual call
- writeToCurrentMethodFragment("//Do your thing\n");
- writeToCurrentMethodFragment(wrappedPtrCall);
- writeToCurrentMethodFragment("\n");
+ std::string mbMethodName = Char(overloaded_name_qualified);
+ ExceptionCodeWriter writer(meth, mbMethodName, "MG_TRY", "MG_CATCH", true);
+ {
+ Indenter ind2(m_indentationLevels);
+ if (parms)
+ {
+ std::string funcCallArgsStr;
+ getFunctionArgumentAssignmentCode(parms, meth, funcCallArgsStr);
+ wrappedPtrCall += Char(name);
+ wrappedPtrCall += "(";
+ wrappedPtrCall += funcCallArgsStr;
+ wrappedPtrCall += ");\n";
+ }
+ else
+ {
+ meth.writeToFragment("//Function has no arguments\n");
+ wrappedPtrCall += Char(name);
+ wrappedPtrCall += "();\n";
+ }
+
+ meth.writeToFragment(NewStringf("%s* proxy = node::ObjectWrap::Unwrap<%s>(%s.This());\n", proxyClsName.c_str(), proxyClsName.c_str(), ARGS_VAR));
+ meth.writeToFragment(NewStringf("%s = proxy->GetInternalPointer();\n", WRAPPED_PTR_VAR));
+
+ //Here's the actual call
+ meth.writeToFragment("//Do your thing\n");
+ meth.writeToFragment(wrappedPtrCall);
+ meth.writeToFragment("\n");
- writeToCurrentMethodFragment(NewStringf("MG_CATCH(L\"%s::%s\")\n", proxyClsName.c_str(), overloaded_name_qualified));
- writeToCurrentMethodFragment("if (mgException != NULL)\n");
- writeToCurrentMethodFragment("{\n");
- {
- Indenter ind2(m_indentationLevels);
- writeToCurrentMethodFragment("//NOTE: Unlike previous iterations of the MapGuide API, MgException::GetDetails() finally gives us *everything*\n");
- writeToCurrentMethodFragment("STRING details = mgException->GetDetails();\n");
- writeToCurrentMethodFragment("std::string mbDetails = MgUtil::WideCharToMultiByte(details);\n");
- writeToCurrentMethodFragment("v8::Local<v8::Value> v8ex = v8::Exception::Error(v8::String::New(mbDetails.c_str()));\n");
- writeToCurrentMethodFragment("//Release our MgException before throwing the v8 one\n");
- writeToCurrentMethodFragment("mgException = NULL;\n");
- if (isCurrentClassMgObject())
- writeToCurrentMethodFragment(NewStringf("if (%s) { ((MgDisposable*)%s)->Release(); %s = NULL; }\n", WRAPPED_PTR_VAR, WRAPPED_PTR_VAR, WRAPPED_PTR_VAR));
- writeToCurrentMethodFragment("return v8::ThrowException(v8ex);\n");
+ }
}
- writeToCurrentMethodFragment("}\n");
if (isCurrentClassMgObject())
- writeToCurrentMethodFragment(NewStringf("if (%s) { ((MgDisposable*)%s)->Release(); %s = NULL; }\n", WRAPPED_PTR_VAR, WRAPPED_PTR_VAR, WRAPPED_PTR_VAR));
- //writeToCurrentMethodFragment("v8::HandleScope scope;\n");
- //writeToCurrentMethodFragment("return scope.Close();\n");
+ meth.writeToFragment(NewStringf("if (%s) { ((MgDisposable*)%s)->Release(); %s = NULL; }\n", WRAPPED_PTR_VAR, WRAPPED_PTR_VAR, WRAPPED_PTR_VAR));
+ //meth.writeToFragment("v8::HandleScope scope;\n");
+ //meth.writeToFragment("return scope.Close();\n");
- writeToCurrentMethodFragment("\n");
- writeToCurrentMethodFragment("//Return value to javascript\n");
+ meth.writeToFragment("\n");
+ meth.writeToFragment("//Return value to javascript\n");
if (isVoid)
{
- writeToCurrentMethodFragment("return v8::Undefined();\n");
+ meth.writeToFragment("return v8::Undefined();\n");
}
else
{
if (isMgPointer) //Stub
{
- writeToCurrentMethodFragment("return v8::ThrowException(v8::Exception::Error(v8::String::New(\"TODO: Case not handled yet: Returning objects\")));\n");
+ meth.writeToFragment("return v8::ThrowException(v8::Exception::Error(v8::String::New(\"TODO: Case not handled yet: Returning objects\")));\n");
}
else
{
std::string scopeCloseCall;
std::string preCloseCallCode;
- writeToCurrentMethodFragment("v8::HandleScope scope;\n");
+ meth.writeToFragment("v8::HandleScope scope;\n");
if (isMgPointer)
{
@@ -682,12 +728,12 @@
getScopeCloseCallForBasicType(retType, scopeCloseCall, preCloseCallCode);
}
if (!preCloseCallCode.empty())
- writeToCurrentMethodFragment(preCloseCallCode);
- writeToCurrentMethodFragment(NewStringf("return scope.Close(%s);\n", scopeCloseCall.c_str()));
+ meth.writeToFragment(preCloseCallCode);
+ meth.writeToFragment(NewStringf("return scope.Close(%s);\n", scopeCloseCall.c_str()));
}
}
}
- writeToCurrentMethodFragment("}\n");
+ meth.writeToFragment("}\n");
String* regCall = NewStringf(
"%s->PrototypeTemplate()->Set(v8::String::NewSymbol(\"%s\"), v8::FunctionTemplate::New(%s)->GetFunction());\n",
@@ -705,7 +751,7 @@
return SWIG_OK;
}
- void getFunctionArgumentAssignmentCode(ParmList* parms, std::string& nativeMethodArgsString)
+ void getFunctionArgumentAssignmentCode(ParmList* parms, FragmentWriter& frag, std::string& nativeMethodArgsString, bool bThrowV8Exceptions = true)
{
int argNo = 0;
Parm *p;
@@ -718,21 +764,26 @@
bool isArgMgPointer = !SwigType_issimple(type);
- writeToCurrentMethodFragment("//Argument\n");
- writeToCurrentMethodFragment(NewStringf("// Name - %s\n", name));
- writeToCurrentMethodFragment(NewStringf("// Type - %s\n", type));
- //writeToCurrentMethodFragment(NewStringf("// Value - %s\n", value));
+ frag.writeToFragment("//Argument\n");
+ frag.writeToFragment(NewStringf("// Name - %s\n", name));
+ frag.writeToFragment(NewStringf("// Type - %s\n", type));
+ //frag.writeToFragment(NewStringf("// Value - %s\n", value));
- //Before we extract values from v8::Arguments, do basic checks on primitive
- //types
+ //Before we extract values from v8::Arguments, do basic checks on the parameters
if (isArgMgPointer)
{
- writeToCurrentMethodFragment(NewStringf("if (!args[%d]->IsObject()) return v8::ThrowException(v8::Exception::Error(v8::String::New(\"Argument %d (%s: %s) is not an object\")));\n", argNo, (argNo + 1), name, type));
+ if (bThrowV8Exceptions)
+ frag.writeToFragment(NewStringf("if (!%s[%d]->IsObject()) return v8::ThrowException(v8::Exception::Error(v8::String::New(\"Argument %d (%s: %s) is not an object\")));\n", ARGS_VAR, argNo, (argNo + 1), name, type));
+ else
+ frag.writeToFragment(NewStringf("if (!%s[%d]->IsObject()) throw new MgInvalidArgumentException(L\"\", __LINE__, __WFILE__, NULL, L\"\", NULL);\n", ARGS_VAR, argNo));
}
else
{
//Write definition check
- writeToCurrentMethodFragment(NewStringf("if (args[%d]->IsUndefined()) return v8::ThrowException(v8::Exception::Error(v8::String::New(\"Argument %d (%s: %s) is undefined\")));\n", argNo, (argNo + 1), name, type));
+ if (bThrowV8Exceptions)
+ frag.writeToFragment(NewStringf("if (%s[%d]->IsUndefined()) return v8::ThrowException(v8::Exception::Error(v8::String::New(\"Argument %d (%s: %s) is undefined\")));\n", ARGS_VAR, argNo, (argNo + 1), name, type));
+ else
+ frag.writeToFragment(NewStringf("if (!%s[%d]->IsUndefined()) throw new MgInvalidArgumentException(L\"\", __LINE__, __WFILE__, NULL, L\"\", NULL);\n", ARGS_VAR, argNo));
//Then type check
if (Strcmp(type, "BYTE") == 0 ||
Strcmp(type, "INT8") == 0 ||
@@ -747,37 +798,61 @@
Strcmp(type, "long") == 0 ||
Strcmp(type, "long long") == 0)
{
- writeToCurrentMethodFragment(NewStringf("if (!args[%d]->IsInt32()) return v8::ThrowException(v8::Exception::Error(v8::String::New(\"Argument %d (%s: %s) is not a number\")));\n", argNo, (argNo + 1), name, type));
+ if (bThrowV8Exceptions)
+ frag.writeToFragment(NewStringf("if (!%s[%d]->IsInt32()) return v8::ThrowException(v8::Exception::Error(v8::String::New(\"Argument %d (%s: %s) is not a number\")));\n", ARGS_VAR, argNo, (argNo + 1), name, type));
+ else
+ frag.writeToFragment(NewStringf("if (!%s[%d]->IsInt32()) throw new MgInvalidArgumentException(L\"\", __LINE__, __WFILE__, NULL, L\"\", NULL);\n", ARGS_VAR, argNo));
}
else if (Strcmp(type, "double") == 0 ||
Strcmp(type, "float") == 0)
{
- writeToCurrentMethodFragment(NewStringf("if (!args[%d]->IsNumber()) return v8::ThrowException(v8::Exception::Error(v8::String::New(\"Argument %d (%s: %s) is not a number\")));\n", argNo, (argNo + 1), name, type));
+ if (bThrowV8Exceptions)
+ frag.writeToFragment(NewStringf("if (!%s[%d]->IsNumber()) return v8::ThrowException(v8::Exception::Error(v8::String::New(\"Argument %d (%s: %s) is not a number\")));\n", ARGS_VAR, argNo, (argNo + 1), name, type));
+ else
+ frag.writeToFragment(NewStringf("if (!%s[%d]->IsNumber()) throw new MgInvalidArgumentException(L\"\", __LINE__, __WFILE__, NULL, L\"\", NULL);\n", ARGS_VAR, argNo));
}
else if (Strcmp(type, "STRINGPARAM") == 0)
{
- writeToCurrentMethodFragment(NewStringf("if (!args[%d]->IsString()) return v8::ThrowException(v8::Exception::Error(v8::String::New(\"Argument %d (%s: %s) is not a string\")));\n", argNo, (argNo + 1), name, type));
+ if (bThrowV8Exceptions)
+ frag.writeToFragment(NewStringf("if (!%s[%d]->IsString()) return v8::ThrowException(v8::Exception::Error(v8::String::New(\"Argument %d (%s: %s) is not a string\")));\n", ARGS_VAR, argNo, (argNo + 1), name, type));
+ else
+ frag.writeToFragment(NewStringf("if (!%s[%d]->IsString()) throw new MgInvalidArgumentException(L\"\", __LINE__, __WFILE__, NULL, L\"\", NULL);\n", ARGS_VAR, argNo));
}
else if (Strcmp(type, "bool") == 0)
{
- writeToCurrentMethodFragment(NewStringf("if (!args[%d]->IsBoolean()) return v8::ThrowException(v8::Exception::Error(v8::String::New(\"Argument %d (%s: %s) is not a boolean\")));\n", argNo, (argNo + 1), name, type));
+ if (bThrowV8Exceptions)
+ frag.writeToFragment(NewStringf("if (!%s[%d]->IsBoolean()) return v8::ThrowException(v8::Exception::Error(v8::String::New(\"Argument %d (%s: %s) is not a boolean\")));\n", ARGS_VAR, argNo, (argNo + 1), name, type));
+ else
+ frag.writeToFragment(NewStringf("if (!%s[%d]->IsBoolean()) throw new MgInvalidArgumentException(L\"\", __LINE__, __WFILE__, NULL, L\"\", NULL);\n", ARGS_VAR, argNo));
}
}
+ bool bIsMgObject = (Strcmp(typeUnprefixed, "MgObject") == 0);
+
if (isArgMgPointer)
{
std::string proxyClsName;
setProxyClassName(typeUnprefixed, proxyClsName);
- writeToCurrentMethodFragment(NewStringf("Ptr<%s> arg%d = NULL;\n", typeUnprefixed, argNo));
- writeToCurrentMethodFragment(NewStringf("%s* proxyArg%d = NULL;\n", proxyClsName.c_str(), argNo));
- writeToCurrentMethodFragment(NewStringf("if (!args[%d]->IsUndefined())\n", argNo));
- writeToCurrentMethodFragment("{\n");
+ if (bIsMgObject)
{
+ frag.writeToFragment(NewStringf("Ptr<MgDisposable> arg%d = NULL;\n", argNo));
+ }
+ else
+ {
+ frag.writeToFragment(NewStringf("Ptr<%s> arg%d = NULL;\n", typeUnprefixed, argNo));
+ }
+ frag.writeToFragment(NewStringf("%s* proxyArg%d = NULL;\n", proxyClsName.c_str(), argNo));
+ frag.writeToFragment(NewStringf("if (!%s[%d]->IsUndefined())\n", ARGS_VAR, argNo));
+ frag.writeToFragment("{\n");
+ {
Indenter ind(m_indentationLevels);
- writeToCurrentMethodFragment(NewStringf("proxyArg%d = node::ObjectWrap::Unwrap<%s>(args[%d]->ToObject());\n", argNo, proxyClsName.c_str(), argNo));
- writeToCurrentMethodFragment(NewStringf("arg%d = proxyArg%d->GetInternalPointer();\n", argNo, argNo));
+ frag.writeToFragment(NewStringf("proxyArg%d = node::ObjectWrap::Unwrap<%s>(%s[%d]->ToObject());\n", argNo, proxyClsName.c_str(), ARGS_VAR, argNo));
+ if (bIsMgObject)
+ frag.writeToFragment(NewStringf("arg%d = (MgDisposable*)proxyArg%d->GetInternalPointer();\n", argNo, argNo));
+ else
+ frag.writeToFragment(NewStringf("arg%d = proxyArg%d->GetInternalPointer();\n", argNo, argNo));
}
- writeToCurrentMethodFragment("}\n");
+ frag.writeToFragment("}\n");
}
else
{
@@ -795,33 +870,41 @@
Strcmp(type, "long") == 0 ||
Strcmp(type, "long long") == 0)
{
- writeToCurrentMethodFragment(NewStringf("%s arg%d = (%s)args[%d]->IntegerValue();\n", type, argNo, type, argNo));
+ frag.writeToFragment(NewStringf("%s arg%d = (%s)%s[%d]->IntegerValue();\n", type, argNo, type, ARGS_VAR, argNo));
}
else if (Strcmp(type, "double") == 0 ||
Strcmp(type, "float") == 0)
{
- writeToCurrentMethodFragment(NewStringf("%s arg%d = (%s)args[%d]->NumberValue();\n", type, argNo, type, argNo));
+ frag.writeToFragment(NewStringf("%s arg%d = (%s)%s[%d]->NumberValue();\n", type, argNo, type, ARGS_VAR, argNo));
}
else if (Strcmp(type, "BYTE_ARRAY_OUT") == 0)
{
- //writeToCurrentMethodFragment(NewStringf("std::string str%d = args[%d]->ToString();\n", argNo, argNo));
- //writeToCurrentMethodFragment(NewStringf("Ptr<MgByte> bytes%d = new MgByte((BYTE_ARRAY_IN)str%d);\n", argNo, argNo));
- //writeToCurrentMethodFragment(NewStringf("STRING arg%d = MgUtil::MultiByteToWideChar(args[%d]->ToString());\n", argNo, argNo));
- writeToCurrentMethodFragment("//TODO: Case not handled: BYTE_ARRAY_OUT\n");
- writeToCurrentMethodFragment(NewStringf("BYTE_ARRAY_OUT arg%d = NULL;\n", argNo));
+ //frag.writeToFragment(NewStringf("std::string str%d = args[%d]->ToString();\n", argNo, argNo));
+ //frag.writeToFragment(NewStringf("Ptr<MgByte> bytes%d = new MgByte((BYTE_ARRAY_IN)str%d);\n", argNo, argNo));
+ //frag.writeToFragment(NewStringf("STRING arg%d = MgUtil::MultiByteToWideChar(args[%d]->ToString());\n", argNo, argNo));
+ frag.writeToFragment("//TODO: Case not handled: BYTE_ARRAY_OUT\n");
+ frag.writeToFragment(NewStringf("BYTE_ARRAY_OUT arg%d = NULL;\n", argNo));
}
+ else if (Strcmp(type, "BYTE_ARRAY_IN") == 0)
+ {
+ //frag.writeToFragment(NewStringf("std::string str%d = args[%d]->ToString();\n", argNo, argNo));
+ //frag.writeToFragment(NewStringf("Ptr<MgByte> bytes%d = new MgByte((BYTE_ARRAY_IN)str%d);\n", argNo, argNo));
+ //frag.writeToFragment(NewStringf("STRING arg%d = MgUtil::MultiByteToWideChar(args[%d]->ToString());\n", argNo, argNo));
+ frag.writeToFragment("//TODO: Case not handled: BYTE_ARRAY_IN\n");
+ frag.writeToFragment(NewStringf("BYTE_ARRAY_IN arg%d = NULL;\n", argNo));
+ }
else if (Strcmp(type, "STRINGPARAM") == 0)
{
- writeToCurrentMethodFragment(NewStringf("v8::String::Utf8Value mbArg%d(args[%d]->ToString());\n", argNo, argNo));
- writeToCurrentMethodFragment(NewStringf("STRING arg%d = MgUtil::MultiByteToWideChar(std::string(*mbArg%d));\n", argNo, argNo));
+ frag.writeToFragment(NewStringf("v8::String::Utf8Value mbArg%d(%s[%d]->ToString());\n", argNo, ARGS_VAR, argNo));
+ frag.writeToFragment(NewStringf("STRING arg%d = MgUtil::MultiByteToWideChar(std::string(*mbArg%d));\n", argNo, argNo));
}
else if (Strcmp(type, "bool") == 0)
{
- writeToCurrentMethodFragment(NewStringf("%s arg%d = args[%d]->BooleanValue();\n", type, argNo, argNo));
+ frag.writeToFragment(NewStringf("%s arg%d = %s[%d]->BooleanValue();\n", type, argNo, ARGS_VAR, argNo));
}
}
- writeToCurrentMethodFragment("\n");
+ frag.writeToFragment("\n");
if (!nativeMethodArgsString.empty())
nativeMethodArgsString += ", ";
@@ -881,7 +964,8 @@
virtual int membervariableHandler(Node* n)
{
String* name = Getattr(n, "sym:name");
- writeToCurrentClassFragment(NewStringf("//\tMember Variable: %s::%s\n", m_currentClassName, name));
+ FragmentWriter frag(m_indentationLevels, m_currentFragment);
+ frag.writeToFragment(NewStringf("//\tMember Variable: %s::%s\n", m_currentClassName, name));
String* swExpCall = NewStringf("//TODO: Export member variable %s::%s", m_currentClassName, name);
std::string expCall = Char(swExpCall);
More information about the mapguide-commits
mailing list