Fix %nspace support and activated relevant tests.

This commit is contained in:
Oliver Buchtala 2013-09-24 01:47:13 +02:00
commit 8bf966a65c
7 changed files with 181 additions and 42 deletions

View file

@ -15,10 +15,10 @@ namespace Bar
FooBar() {}
FooBar(const FooBar&) {}
virtual ~FooBar() {}
std::string FooBarDo() { return "Bar::Foo2::Foo2Bar()"; }
};
class Foo {
public:
virtual ~Foo() {}
@ -37,7 +37,7 @@ namespace Bar
%include <std_string.i>
// nspace feature only supported by these languages
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD)
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGJAVASCRIPT)
%nspace Bar::Foo;
%nspace Bar::FooBar;
#else
@ -47,17 +47,17 @@ namespace Bar
%feature("director") Bar::Foo;
namespace Bar
{
{
class FooBar {
public:
FooBar();
FooBar(const FooBar&);
virtual ~FooBar();
std::string FooBarDo();
};
class Foo
{
public:
@ -67,7 +67,7 @@ namespace Bar
virtual std::string fooBar(FooBar* fb);
virtual Foo makeFoo();
virtual FooBar makeFooBar();
static Foo* get_self(Foo *self_);
};
}

View file

@ -45,6 +45,8 @@ CPP_TEST_CASES = \
cpp_static \
enum_template \
namespace_virtual_method \
nspace \
nspace_extend \
overload_copy \
rename_simple \
rename_scope \

View file

@ -0,0 +1,27 @@
var nspace_extend = require("./nspace_extend");
// constructors and destructors
var color1 = new nspace_extend.Outer.Inner1.Color();
var color = new nspace_extend.Outer.Inner1.Color(color1);
delete color1;
// class methods
color.colorInstanceMethod(20.0);
nspace_extend.Outer.Inner1.Color.colorStaticMethod(20.0);
var created = nspace_extend.Outer.Inner1.Color.create();
// constructors and destructors
var color2 = new nspace_extend.Outer.Inner2.Color();
color = new nspace_extend.Outer.Inner2.Color(color2);
delete color2;
// class methods
color.colorInstanceMethod(20.0);
nspace_extend.Outer.Inner2.Color.colorStaticMethod(20.0);
created = nspace_extend.Outer.Inner2.Color.create();
// Same class different namespaces
var col1 = new nspace_extend.Outer.Inner1.Color();
var col2 = nspace_extend.Outer.Inner2.Color.create();
col2.colors(col1, col1, col2, col2, col2);

View file

@ -0,0 +1,77 @@
var nspace = require("./nspace");
var color1 = new nspace.Outer.Inner1.Color();
var color = new nspace.Outer.Inner1.Color(color1);
delete color1;
// class methods
color.colorInstanceMethod(20.0);
nspace.Outer.Inner1.Color.colorStaticMethod(20.0);
var created = nspace.Outer.Inner1.Color.create();
// class enums
var someClass = new nspace.Outer.SomeClass();
var channel = someClass.GetInner1ColorChannel();
if (channel != nspace.Outer.Inner1.Color.Transmission) {
throw new Error("Failed.");
}
// class anonymous enums
var val1 = nspace.Outer.Inner1.Color.ColorEnumVal1;
var val2 = nspace.Outer.Inner1.Color.ColorEnumVal2;
if (val1 !== 0 || val2 !== 0x22) {
throw new Error("Failed.");
}
// instance member variables
color.instanceMemberVariable = 123;
if (color.instanceMemberVariable !== 123) {
throw new Error("Failed.");
}
// static member variables
nspace.Outer.Inner1.Color.staticMemberVariable = 789;
if (nspace.Outer.Inner1.Color.staticMemberVariable !== 789) {
throw new Error("Failed.");
}
if (nspace.Outer.Inner1.Color.staticConstMemberVariable !== 222) {
throw new Error("Failed.");
}
if (nspace.Outer.Inner1.Color.staticConstEnumMemberVariable !== nspace.Outer.Inner1.Color.Transmission) {
throw new Error("Failed.");
}
// Same class different namespaces
var col1 = new nspace.Outer.Inner1.Color();
var col2 = nspace.Outer.Inner2.Color.create();
col2.colors(col1, col1, col2, col2, col2);
// TODO: why isn't it scoped in the namespace???
nspace.namespaceFunction(color);
nspace.Outer.Inner1.namespaceVar = 111;
if (nspace.Outer.Inner1.namespaceVar !== 111) {
throw new Error("Failed.");
}
// global enums
var outerChannel1 = someClass.GetInner1Channel();
if (outerChannel1 != nspace.Outer.Inner1.Transmission1) {
throw new Error("Failed.");
}
var outerChannel2 = someClass.GetInner2Channel();
if (outerChannel2 !== nspace.Outer.Inner2.Transmission2) {
throw new Error("Failed.");
}
// turn feature off / ignoring
var ns = new nspace.Outer.namespce();
var nons = new nspace.NoNSpacePlease();
// Derived class
var blue3 = new nspace.Outer.Inner3.Blue();
blue3.blueInstanceMethod();
var blue4 = new nspace.Outer.Inner4.Blue();
blue4.blueInstanceMethod();

View file

@ -2,7 +2,7 @@
%module nspace
// nspace feature only supported by these languages
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD)
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGJAVASCRIPT)
#if defined(SWIGJAVA)
SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)

View file

@ -2,7 +2,7 @@
%module nspace_extend
// nspace feature only supported by these languages
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD)
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGJAVASCRIPT)
#if defined(SWIGJAVA)
SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)

View file

@ -396,7 +396,6 @@ int JAVASCRIPT::variableHandler(Node *n) {
* --------------------------------------------------------------------- */
int JAVASCRIPT::globalvariableHandler(Node *n) {
emitter->switchNamespace(n);
Language::globalvariableHandler(n);
@ -410,6 +409,7 @@ int JAVASCRIPT::globalvariableHandler(Node *n) {
* --------------------------------------------------------------------- */
int JAVASCRIPT::constantWrapper(Node *n) {
emitter->switchNamespace(n);
// Note: callbacks trigger this wrapper handler
// TODO: handle callback declarations
@ -464,7 +464,6 @@ int JAVASCRIPT::fragmentDirective(Node *n) {
* --------------------------------------------------------------------- */
int JAVASCRIPT::top(Node *n) {
emitter->initialize(n);
Language::top(n);
@ -482,7 +481,6 @@ int JAVASCRIPT::top(Node *n) {
* --------------------------------------------------------------------- */
void JAVASCRIPT::main(int argc, char *argv[]) {
// Set javascript subdirectory in SWIG library
SWIG_library_directory("javascript");
@ -667,7 +665,7 @@ int JSEmitter::emitWrapperFunction(Node *n) {
if (kind) {
if (Cmp(kind, "function") == 0) {
bool is_member = GetFlag(n, "ismember");
bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend");
bool is_static = GetFlag(state.function(), IS_STATIC);
ret = emitFunction(n, is_member, is_static);
} else if (Cmp(kind, "variable") == 0) {
@ -707,18 +705,23 @@ int JSEmitter::emitWrapperFunction(Node *n) {
}
int JSEmitter::enterClass(Node *n) {
state.clazz(true);
state.clazz(NAME, Getattr(n, "sym:name"));
//state.clazz(NAME_MANGLED, SwigType_manglestr(Getattr(n, "name")));
state.clazz(NAME_MANGLED, Getattr(n, "sym:name"));
state.clazz("nspace", current_namespace);
// Creating a mangled name using the current namespace and the symbol name
String *mangled_name = NewString("");
Printf(mangled_name, "%s_%s", Getattr(current_namespace, NAME_MANGLED), Getattr(n, "sym:name"));
state.clazz(NAME_MANGLED, SwigType_manglestr(mangled_name));
Delete(mangled_name);
state.clazz(TYPE, NewString(Getattr(n, "classtype")));
String *type = SwigType_manglestr(Getattr(n, "classtypeobj"));
String *classtype_mangled = NewString("");
Printf(classtype_mangled, "p%s", type);
Delete(type);
state.clazz(TYPE_MANGLED, classtype_mangled);
Delete(type);
String *ctor_wrapper = NewString("_wrap_new_veto_");
Append(ctor_wrapper, state.clazz(NAME));
@ -734,23 +737,19 @@ int JSEmitter::enterClass(Node *n) {
}
int JSEmitter::enterFunction(Node *n) {
state.function(true);
state.function(NAME, Getattr(n, "sym:name"));
if(Equal(Getattr(n, "storage"), "static")) {
SetFlag(state.function(), IS_STATIC);
}
return SWIG_OK;
}
int JSEmitter::enterVariable(Node *n) {
// reset the state information for variables.
state.variable(true);
// Retrieve a pure symbol name. Using 'sym:name' as a basis, as it considers %renamings.
if (Equal(Getattr(n, "view"), "memberconstantHandler")) {
// Note: this is kind of hacky/experimental
// For constants/enums 'sym:name' contains e.g., 'Foo_Hello' instead of 'Hello'
@ -763,10 +762,12 @@ int JSEmitter::enterVariable(Node *n) {
SetFlag(state.variable(), IS_STATIC);
}
if (!Language::instance()->is_assignable(n)
// FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[]
// probably some error in char[] typemap
|| Equal(Getattr(n, "type"), "a().char")) {
if (!Language::instance()->is_assignable(n)) {
SetFlag(state.variable(), IS_IMMUTABLE);
}
// FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[]
if (Equal(Getattr(n, "type"), "a().char")) {
SetFlag(state.variable(), IS_IMMUTABLE);
}
@ -1273,23 +1274,43 @@ void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) {
}
int JSEmitter::switchNamespace(Node *n) {
// HACK: somehow this gets called when member functions are processed...ignoring
if (GetFlag(n, "ismember")) {
return SWIG_OK;
}
String *nspace = Getattr(n, "sym:nspace");
// if nspace is deactivated, everything goes into the global scope
if (!GetFlag(n, "feature:nspace")) {
current_namespace = Getattr(namespaces, "::");
} else {
String *scope = Swig_scopename_prefix(Getattr(n, "name"));
if (scope) {
// if the scope is not yet registered
// create (parent) namespaces recursively
if (!Getattr(namespaces, scope)) {
createNamespace(scope);
}
current_namespace = Getattr(namespaces, scope);
} else {
current_namespace = Getattr(namespaces, "::");
return SWIG_OK;
}
if (nspace == NULL) {
// enums and constants do not have 'sym:nspace' set
// so we try to get the namespace from the qualified name
if(Equal(Getattr(n, "nodeType"), "enumitem")) {
nspace = Swig_scopename_prefix(Getattr(n, "name"));
}
}
if (nspace == NULL) {
current_namespace = Getattr(namespaces, "::");
return SWIG_OK;
}
String *scope = NewString(nspace);
// replace "." with "::" that we can use Swig_scopename_last
Replaceall(scope, ".", "::");
// if the scope is not yet registered
// create (parent) namespaces recursively
if (!Getattr(namespaces, scope)) {
createNamespace(scope);
}
current_namespace = Getattr(namespaces, scope);
return SWIG_OK;
}
@ -1434,6 +1455,12 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma
int i = 0;
for (p = parms; p; i++) {
String *arg = NewString("");
String *type = Getattr(p, "type");
// ignore varargs
if (SwigType_isvarargs(type))
break;
switch (mode) {
case Getter:
case Function:
@ -1556,7 +1583,7 @@ int JSCEmitter::enterFunction(Node *n) {
int JSCEmitter::exitFunction(Node *n) {
Template t_function = getTemplate("jsc_function_declaration");
bool is_member = GetFlag(n, "ismember");
bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend");
bool is_overloaded = GetFlag(n, "sym:overloaded");
// handle overloaded functions
@ -1682,7 +1709,7 @@ int JSCEmitter::exitClass(Node *n) {
Template t_registerclass(getTemplate("jsc_class_registration"));
t_registerclass.replace("$jsname", state.clazz(NAME))
.replace("$jsmangledname", state.clazz(NAME_MANGLED))
.replace("$jsnspace", Getattr(current_namespace, NAME_MANGLED))
.replace("$jsnspace", Getattr(state.clazz("nspace"),NAME_MANGLED))
.pretty_print(state.global(INITIALIZER));
return SWIG_OK;
@ -1973,7 +2000,7 @@ int V8Emitter::exitClass(Node *n)
Template t_register = getTemplate("jsv8_register_class");
t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
.replace("$jsname", state.clazz(NAME))
.replace("$jsparent", Getattr(current_namespace, "name_mangled"))
.replace("$jsparent", Getattr(state.clazz("nspace"),NAME_MANGLED))
.trim()
.pretty_print(f_init_register_classes);
@ -2014,7 +2041,7 @@ int V8Emitter::exitVariable(Node* n)
// Note: a global variable is treated like a static variable
// with the parent being a nspace object (instead of class object)
Template t_register = getTemplate("jsv8_register_static_variable");
t_register.replace("$jsparent", Getattr(current_namespace, NAME))
t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED))
.replace("$jsname", state.variable(NAME))
.replace("$jsgetter", state.variable(GETTER))
.replace("$jssetter", state.variable(SETTER))
@ -2027,7 +2054,7 @@ int V8Emitter::exitVariable(Node* n)
int V8Emitter::exitFunction(Node* n)
{
bool is_member = GetFlag(n, "ismember");
bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend");
// create a dispatcher for overloaded functions
bool is_overloaded = GetFlag(n, "sym:overloaded");
@ -2090,6 +2117,12 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar
int i = 0;
for (p = parms; p; i++) {
String *arg = NewString("");
String *type = Getattr(p, "type");
// ignore varargs
if (SwigType_isvarargs(type))
break;
switch (mode) {
case Getter:
if (is_member && !is_static && i == 0) {