[mapguide-commits] r7627 - sandbox/jng/node/Oem/SWIGEx/Source/Modules
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Tue Jun 18 07:37:13 PDT 2013
Author: jng
Date: 2013-06-18 07:37:13 -0700 (Tue, 18 Jun 2013)
New Revision: 7627
Modified:
sandbox/jng/node/Oem/SWIGEx/Source/Modules/nodejs.cxx
Log:
This submission allows the generated NodeJS binding to do basic parameter and return value marshalling for its proxy class methods and also generates a (currently empty) hook function which will apply the necessary JS prototype inheritance chains.
Modified: sandbox/jng/node/Oem/SWIGEx/Source/Modules/nodejs.cxx
===================================================================
--- sandbox/jng/node/Oem/SWIGEx/Source/Modules/nodejs.cxx 2013-06-17 04:48:27 UTC (rev 7626)
+++ sandbox/jng/node/Oem/SWIGEx/Source/Modules/nodejs.cxx 2013-06-18 14:37:13 UTC (rev 7627)
@@ -1,9 +1,14 @@
#include "swigmod.h"
#include <vector>
+#include <sstream>
#define EXPORTS_VAR "exports"
#define CLASS_EXPORT_VAR "tpl"
#define CLASS_PROXY_CTOR_NAME "New"
+#define BASE_CLASS_FUNC_TEMPLATE_VAR "baseCls"
+#define WRAPPED_PTR_VAR "wrappedPtr"
+#define FUNC_RET_VAR "retVal"
+#define ARGS_VAR "args"
class Indenter
{
@@ -24,11 +29,18 @@
String* m_namespace;
String* m_currentClassName;
File* m_fOutputFile;
+ std::vector<std::string> m_classFwdDecls;
std::vector<std::string> m_classDecls;
+ std::vector<std::string> m_classMethodDecls;
std::vector<std::string> m_classExportCalls;
+ std::vector<std::string> m_classInheritCalls;
std::vector<std::string> m_classMemberExportCalls;
+ std::vector<std::string> m_classSetupCalls;
std::string m_currentFragment;
std::string m_currentExportFragment;
+ std::string m_currentInheritFragment;
+ std::string m_currentMethodFragment;
+ std::string m_currentClassSetupFragment;
int m_indentationLevels;
public:
@@ -95,8 +107,25 @@
writeToFile("#include \"WebSupport.h\"\n");
writeToFile("#include \"HttpHandler.h\"\n\n\n");
+ // Due to C++ being sensitive to order of types declared (we are outputting this all into one big .cpp file)
+ // We have to output the generated code in chunks, as shown below
+ //
+ //
+
Language::top(n);
+ writeToFile("//=====================================\n");
+ writeToFile("//Forward declarations\n");
+ writeToFile("//=====================================\n");
+ for (std::vector<std::string>::iterator it = m_classFwdDecls.begin(); it != m_classFwdDecls.end(); it++)
+ {
+ std::string call = (*it);
+ writeToFile(call);
+ writeToFile("\n");
+ }
+ writeToFile("//=====================================\n");
+ writeToFile("//Proxy class definitions\n");
+ writeToFile("//=====================================\n");
for (std::vector<std::string>::iterator it = m_classDecls.begin(); it != m_classDecls.end(); it++)
{
std::string call = (*it);
@@ -104,6 +133,26 @@
writeToFile("\n");
}
+ writeToFile("//=====================================\n");
+ writeToFile("//Proxy class method definitions\n");
+ writeToFile("//=====================================\n");
+ for (std::vector<std::string>::iterator it = m_classMethodDecls.begin(); it != m_classMethodDecls.end(); it++)
+ {
+ std::string call = (*it);
+ writeToFile(call);
+ writeToFile("\n");
+ }
+
+ writeToFile("//=====================================\n");
+ writeToFile("//Proxy class setup methods\n");
+ writeToFile("//=====================================\n");
+ for (std::vector<std::string>::iterator it = m_classSetupCalls.begin(); it != m_classSetupCalls.end(); it++)
+ {
+ std::string call = (*it);
+ writeToFile(call);
+ writeToFile("\n");
+ }
+
writeToFile(NewStringf("extern \"C\" void init(v8::Handle<v8::Object> %s) {\n", EXPORTS_VAR));
{
Indenter ind(m_indentationLevels);
@@ -113,6 +162,13 @@
writeToFile(call);
writeToFile("\n");
}
+
+ for (std::vector<std::string>::iterator it = m_classInheritCalls.begin(); it != m_classInheritCalls.end(); it++)
+ {
+ std::string call = (*it);
+ writeToFile(call);
+ writeToFile("\n");
+ }
}
writeToFile("}\n");
writeToFile(NewStringf("NODE_MODULE(%s, init)\n", modName));
@@ -131,7 +187,7 @@
if (Strstr(name, entry))
{
writeToFile(NewStringf("//Global Function: %s\n", name));
- writeToFile(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& args) {\n", name));
+ writeToFile(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& %s) {\n", name, ARGS_VAR));
{
Indenter ind(m_indentationLevels);
//writeToFile("v8::HandleScope scope;\n");
@@ -144,7 +200,7 @@
{
String* ovName = getOverloadedName(n);
writeToCurrentClassFragment(NewStringf("//ctor Function Wrapper: %s\n", name));
- writeToCurrentClassFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& args) {\n", ovName));
+ writeToCurrentClassFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& %s) {\n", ovName, ARGS_VAR));
{
Indenter ind(m_indentationLevels);
//writeToCurrentClassFragment("v8::HandleScope scope;\n");
@@ -156,7 +212,7 @@
else if (Strstr(name, dtorPrefix))
{
writeToCurrentClassFragment(NewStringf("//dtor Function Wrapper: %s\n", name));
- writeToCurrentClassFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& args) {\n", name));
+ writeToCurrentClassFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& %s) {\n", name, ARGS_VAR));
{
Indenter ind(m_indentationLevels);
//writeToCurrentClassFragment("v8::HandleScope scope;\n");
@@ -169,23 +225,74 @@
return SWIG_OK;
}
- void writeTabs()
+ void writeTabsToCurrentClassSetupFragment()
{
if (m_indentationLevels > 0)
{
for (int i = 0; i < m_indentationLevels; i++)
{
- Printf(m_fOutputFile, "\t");
+ m_currentClassSetupFragment += "\t";
}
}
}
- void writeTabsToCurrentFragment()
+ 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";
}
}
@@ -193,7 +300,7 @@
void writeToCurrentClassFragment(String* str, bool bDelete = true)
{
- writeTabsToCurrentFragment();
+ writeTabsToCurrentClassFragment();
m_currentFragment += Char(str);
if (bDelete)
Delete(str);
@@ -201,19 +308,30 @@
void writeToCurrentClassFragment(const std::string& str)
{
- writeTabsToCurrentFragment();
+ writeTabsToCurrentClassFragment();
m_currentFragment += str;
}
void writeToCurrentClassFragment(const char* str)
{
- writeTabsToCurrentFragment();
+ writeTabsToCurrentClassFragment();
m_currentFragment += str;
}
+
+ void writeTabsToFile()
+ {
+ if (m_indentationLevels > 0)
+ {
+ for (int i = 0; i < m_indentationLevels; i++)
+ {
+ Printf(m_fOutputFile, "\t");
+ }
+ }
+ }
void writeToFile(String* str, bool bDelete = true)
{
- writeTabs();
+ writeTabsToFile();
Printf(m_fOutputFile, "%s", str);
if (bDelete)
Delete(str);
@@ -221,13 +339,13 @@
void writeToFile(const std::string& str)
{
- writeTabs();
+ writeTabsToFile();
Printf(m_fOutputFile, str.c_str());
}
void writeToFile(const char* str)
{
- writeTabs();
+ writeTabsToFile();
Printf(m_fOutputFile, str);
}
@@ -248,7 +366,9 @@
virtual int classHandler(Node* n)
{
m_classMemberExportCalls.clear();
+ m_currentClassSetupFragment = std::string();
m_currentFragment = std::string();
+ m_currentInheritFragment = std::string();
m_currentExportFragment = std::string();
m_currentClassName = NewString(Getattr(n,"sym:name"));
@@ -261,16 +381,27 @@
std::string proxyClsName;
setProxyClassName(m_currentClassName, proxyClsName);
+
+ std::string fwdDecl = "class ";
+ fwdDecl += proxyClsName;
+ fwdDecl += ";";
+ m_classFwdDecls.push_back(fwdDecl);
+
std::string clsHead = "class ";
clsHead += proxyClsName;
clsHead += " : node::ObjectWrap\n";
//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 += EXPORTS_VAR;
+ m_currentInheritFragment += ");";
+
//Unmanaged pointer member
writeToCurrentClassFragment(clsHead);
writeToCurrentClassFragment("{\n");
@@ -345,7 +476,7 @@
//Proxy Constructor
{
Indenter ind(m_indentationLevels);
- writeToCurrentClassFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& args) {\n", CLASS_PROXY_CTOR_NAME));
+ writeToCurrentClassFragment(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");
@@ -357,12 +488,12 @@
//node/v8 export function
{
Indenter ind(m_indentationLevels);
- writeToCurrentClassFragment(NewStringf("static void Export(v8::Handle<v8::Object> %s)\n", EXPORTS_VAR));
- writeToCurrentClassFragment("{\n");
+ writeToCurrentClassSetupFragment(NewStringf("static void %s_Export(v8::Handle<v8::Object> %s)\n", proxyClsName.c_str(), EXPORTS_VAR));
+ writeToCurrentClassSetupFragment("{\n");
{
Indenter ind2(m_indentationLevels);
- writeToCurrentClassFragment(NewStringf("v8::Local<v8::FunctionTemplate> %s = v8::FunctionTemplate::New(%s::%s);\n", CLASS_EXPORT_VAR, proxyClsName.c_str(), CLASS_PROXY_CTOR_NAME));
- writeToCurrentClassFragment(NewStringf("%s->SetClassName(v8::String::NewSymbol(\"%s\"));\n", CLASS_EXPORT_VAR, m_currentClassName));
+ 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));
std::string ctorReg = "v8::Persistent<v8::Function> constructor = v8::Persistent<v8::Function>::New(";
ctorReg += CLASS_EXPORT_VAR;
@@ -379,13 +510,25 @@
for (std::vector<std::string>::iterator it = m_classMemberExportCalls.begin(); it != m_classMemberExportCalls.end(); it++)
{
- writeToCurrentClassFragment((*it));
- writeToCurrentClassFragment("\n");
+ writeToCurrentClassSetupFragment((*it));
+ writeToCurrentClassSetupFragment("\n");
}
}
- writeToCurrentClassFragment("}\n");
+ writeToCurrentClassSetupFragment("}\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");
+ {
+ Indenter ind2(m_indentationLevels);
+ writeToCurrentClassSetupFragment("//TODO: Apply prototype inheritance chain\n");
+ }
+ writeToCurrentClassSetupFragment("}\n");
+ }
+
writeToCurrentClassFragment("};");
Delete(m_currentClassName);
@@ -393,6 +536,8 @@
m_classDecls.push_back(m_currentFragment);
m_classExportCalls.push_back(m_currentExportFragment);
+ m_classInheritCalls.push_back(m_currentInheritFragment);
+ m_classSetupCalls.push_back(m_currentClassSetupFragment);
}
return SWIG_OK;
@@ -409,73 +554,330 @@
return SWIG_OK;
}
- void emitNativeClassMethodCall(Node* n)
- {
- //proxy - The wrapped proxy object pointer
- //wrappedPtr - The native MapGuide object pointer
- writeToCurrentClassFragment("//TODO: Do your thing\n");
- }
-
virtual int memberfunctionHandler(Node* n)
{
String* name = Getattr(n, "sym:name");
+ SwigType *retType = Getattr(n,"type");
+ SwigType *retTypeUnprefixed = SwigType_base(retType);
String* overloaded_name = Copy(getOverloadedName(n));
String* overloaded_name_qualified = Swig_name_member(m_currentClassName, overloaded_name);
+ ParmList *parms = Getattr(n,"parms");
std::string proxyClsName;
setProxyClassName(m_currentClassName, proxyClsName);
- writeToCurrentClassFragment(NewStringf("//\tMember Function: %s::%s\n", m_currentClassName, overloaded_name));
- writeToCurrentClassFragment(NewStringf("static v8::Handle<v8::Value> %s(const v8::Arguments& args) {\n", overloaded_name_qualified));
+ bool isMgPointer = !SwigType_issimple(retType);
+ bool isVoid = (Strcmp(retType, "void") == 0);
+
+ m_currentMethodFragment = std::string();
+
+ //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));
{
Indenter ind(m_indentationLevels);
+
+ std::string wrappedPtrCall;
+ writeToCurrentMethodFragment(NewStringf("//Return type - %s (pointer? %s)\n", retType, (isMgPointer ? "true" : "false")));
+
+ if (isVoid)
+ {
+ writeToCurrentMethodFragment("//Function is void and does not return a value\n");
+ }
+ else
+ {
+ if (isMgPointer)
+ {
+ writeToCurrentMethodFragment(NewStringf("Ptr<%s> %s;\n", retTypeUnprefixed, FUNC_RET_VAR));
+ }
+ else
+ {
+ writeToCurrentMethodFragment(NewStringf("%s %s;\n", retType, FUNC_RET_VAR));
+ }
+ }
+
+ if (!isVoid)
+ {
+ wrappedPtrCall += FUNC_RET_VAR;
+ wrappedPtrCall += " = ";
+ }
+ wrappedPtrCall += WRAPPED_PTR_VAR;
+ wrappedPtrCall += "->";
+
if (isCurrentClassMgObject())
- writeToCurrentClassFragment(NewStringf("%s* wrappedPtr = NULL;\n", m_currentClassName));
+ writeToCurrentMethodFragment(NewStringf("%s* %s = NULL;\n", m_currentClassName, WRAPPED_PTR_VAR));
else
- writeToCurrentClassFragment(NewStringf("Ptr<%s> wrappedPtr;\n", m_currentClassName));
- writeToCurrentClassFragment("MG_TRY()\n");
- writeToCurrentClassFragment(NewStringf("%s* proxy = ObjectWrap::Unwrap<%s>(args.This());\n", proxyClsName.c_str(), proxyClsName.c_str()));
- writeToCurrentClassFragment("wrappedPtr = proxy->GetInternalPointer();\n");
- emitNativeClassMethodCall(n);
- writeToCurrentClassFragment(NewStringf("MG_CATCH(L\"%s::%s\")\n", proxyClsName.c_str(), overloaded_name_qualified));
- writeToCurrentClassFragment("if (mgException != NULL) {\n");
+ writeToCurrentMethodFragment(NewStringf("Ptr<%s> %s;\n", m_currentClassName, WRAPPED_PTR_VAR));
+ writeToCurrentMethodFragment("MG_TRY()\n");
+
+ 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");
+
+ 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);
- writeToCurrentClassFragment("//NOTE: Unlike previous iterations of the MapGuide API, MgException::GetDetails() finally gives us *everything*\n");
- writeToCurrentClassFragment("STRING details = mgException->GetDetails();\n");
- writeToCurrentClassFragment("std::string mbDetails = MgUtil::WideCharToMultiByte(details);\n");
- writeToCurrentClassFragment("v8::Local<v8::Value> v8ex = v8::Exception::Error(v8::String::New(mbDetails.c_str()));\n");
- writeToCurrentClassFragment("//Release our MgException before throwing the v8 one\n");
- writeToCurrentClassFragment("mgException = NULL;\n");
+ 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())
- writeToCurrentClassFragment("if (wrappedPtr) { ((MgDisposable*)wrappedPtr)->Release(); wrappedPtr = NULL; }\n");
- writeToCurrentClassFragment("return v8::ThrowException(v8ex);\n");
+ 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");
}
- writeToCurrentClassFragment("}\n");
+ writeToCurrentMethodFragment("}\n");
if (isCurrentClassMgObject())
- writeToCurrentClassFragment("if (wrappedPtr) { ((MgDisposable*)wrappedPtr)->Release(); wrappedPtr = NULL; }\n");
- //writeToCurrentClassFragment("v8::HandleScope scope;\n");
- //writeToCurrentClassFragment("return scope.Close();\n");
- writeToCurrentClassFragment("return v8::Undefined();\n");
+ 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");
+
+ writeToCurrentMethodFragment("\n");
+ writeToCurrentMethodFragment("//Return value to javascript\n");
+ if (isVoid)
+ {
+ writeToCurrentMethodFragment("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");
+ }
+ else
+ {
+ std::string scopeCloseCall;
+ std::string preCloseCallCode;
+ writeToCurrentMethodFragment("v8::HandleScope scope;\n");
+ if (isMgPointer)
+ {
+
+ }
+ else
+ {
+ getScopeCloseCallForBasicType(retType, scopeCloseCall, preCloseCallCode);
+ }
+ if (!preCloseCallCode.empty())
+ writeToCurrentMethodFragment(preCloseCallCode);
+ writeToCurrentMethodFragment(NewStringf("return scope.Close(%s);\n", scopeCloseCall.c_str()));
+ }
+ }
}
- writeToCurrentClassFragment("}\n");
+ writeToCurrentMethodFragment("}\n");
String* regCall = NewStringf(
- "%s->PrototypeTemplate()->Set(v8::String::NewSymbol(\"%s\"), v8::FunctionTemplate::New(%s::%s)->GetFunction());\n",
+ "%s->PrototypeTemplate()->Set(v8::String::NewSymbol(\"%s\"), v8::FunctionTemplate::New(%s)->GetFunction());\n",
CLASS_EXPORT_VAR,
overloaded_name,
- proxyClsName.c_str(),
overloaded_name_qualified);
std::string sRegCall;
sRegCall += Char(regCall);
m_classMemberExportCalls.push_back(sRegCall);
+ m_classMethodDecls.push_back(m_currentMethodFragment);
Delete(regCall);
Delete(overloaded_name);
return SWIG_OK;
}
+ void getFunctionArgumentAssignmentCode(ParmList* parms, std::string& nativeMethodArgsString)
+ {
+ int argNo = 0;
+ Parm *p;
+ for (p = parms; p; p = nextSibling(p))
+ {
+ SwigType *type = Getattr(p,"type");
+ SwigType *typeUnprefixed = SwigType_base(type);
+ String *name = Getattr(p,"name");
+ //String *value = Getattr(p,"value");
+
+ 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));
+
+ //Before we extract values from v8::Arguments, do basic checks on primitive
+ //types
+ 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));
+ }
+ 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));
+ //Then type check
+ if (Strcmp(type, "BYTE") == 0 ||
+ Strcmp(type, "INT8") == 0 ||
+ Strcmp(type, "INT16") == 0 ||
+ Strcmp(type, "INT32") == 0 ||
+ Strcmp(type, "STATUS") == 0 || //Huh?
+ Strcmp(type, "MgSiteInfo::MgSiteStatus") == 0 || //Huh? I thought MapGuide API doesn't expose enums!
+ Strcmp(type, "MgSiteInfo::MgPortType") == 0 || //Huh? I thought MapGuide API doesn't expose enums!
+ Strcmp(type, "int") == 0 ||
+ Strcmp(type, "UINT32") == 0 ||
+ Strcmp(type, "INT64") == 0 ||
+ 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));
+ }
+ 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));
+ }
+ 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));
+ }
+ 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 (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");
+ {
+ 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));
+ }
+ writeToCurrentMethodFragment("}\n");
+ }
+ else
+ {
+ //Then type check
+ if (Strcmp(type, "BYTE") == 0 ||
+ Strcmp(type, "INT8") == 0 ||
+ Strcmp(type, "INT16") == 0 ||
+ Strcmp(type, "INT32") == 0 ||
+ Strcmp(type, "STATUS") == 0 || //Huh?
+ Strcmp(type, "MgSiteInfo::MgSiteStatus") == 0 || //Huh? I thought MapGuide API doesn't expose enums!
+ Strcmp(type, "MgSiteInfo::MgPortType") == 0 || //Huh? I thought MapGuide API doesn't expose enums!
+ Strcmp(type, "int") == 0 ||
+ Strcmp(type, "UINT32") == 0 ||
+ Strcmp(type, "INT64") == 0 ||
+ Strcmp(type, "long") == 0 ||
+ Strcmp(type, "long long") == 0)
+ {
+ writeToCurrentMethodFragment(NewStringf("%s arg%d = (%s)args[%d]->IntegerValue();\n", type, argNo, type, 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));
+ }
+ 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));
+ }
+ 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));
+ }
+ else if (Strcmp(type, "bool") == 0)
+ {
+ writeToCurrentMethodFragment(NewStringf("%s arg%d = args[%d]->BooleanValue();\n", type, argNo, argNo));
+ }
+ }
+
+ writeToCurrentMethodFragment("\n");
+
+ if (!nativeMethodArgsString.empty())
+ nativeMethodArgsString += ", ";
+
+ nativeMethodArgsString += "arg";
+
+ std::stringstream out;
+ out << argNo;
+ nativeMethodArgsString += out.str();
+
+ argNo++;
+ }
+ }
+
+ void getScopeCloseCallForBasicType(SwigType* type, std::string& str, std::string& preCloseCallCode)
+ {
+ std::string invocation = "(";
+ invocation += FUNC_RET_VAR;
+ invocation += ")";
+ if (Strcmp(type, "BYTE") == 0 ||
+ Strcmp(type, "INT8") == 0 ||
+ Strcmp(type, "INT16") == 0 ||
+ Strcmp(type, "INT32") == 0 ||
+ Strcmp(type, "STATUS") == 0 || //Huh?
+ Strcmp(type, "MgSiteInfo::MgSiteStatus") == 0 || //Huh? I thought MapGuide API doesn't expose enums!
+ Strcmp(type, "int") == 0 ||
+ Strcmp(type, "UINT32") == 0 ||
+ Strcmp(type, "INT64") == 0 ||
+ Strcmp(type, "long") == 0 ||
+ Strcmp(type, "long long") == 0)
+ {
+ str += "v8::Integer::New";
+ str += invocation;
+ }
+ else if (Strcmp(type, "double") == 0 ||
+ Strcmp(type, "float") == 0)
+ {
+ str += "v8::Number::New";
+ str += invocation;
+ }
+ else if (Strcmp(type, "STRING") == 0)
+ {
+ preCloseCallCode += "std::string mbRetVal = MgUtil::WideCharToMultiByte(";
+ preCloseCallCode += FUNC_RET_VAR;
+ preCloseCallCode += ");\n";
+
+ str += "v8::String::New(";
+ str += "mbRetVal.c_str())";
+ }
+ else if (Strcmp(type, "bool") == 0)
+ {
+ str += "v8::Boolean::New";
+ str += invocation;
+ }
+ }
+
virtual int membervariableHandler(Node* n)
{
String* name = Getattr(n, "sym:name");
More information about the mapguide-commits
mailing list