Fix %nspace support and activated relevant tests.
This commit is contained in:
parent
d34a6da08c
commit
8bf966a65c
7 changed files with 181 additions and 42 deletions
|
|
@ -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_);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ CPP_TEST_CASES = \
|
|||
cpp_static \
|
||||
enum_template \
|
||||
namespace_virtual_method \
|
||||
nspace \
|
||||
nspace_extend \
|
||||
overload_copy \
|
||||
rename_simple \
|
||||
rename_scope \
|
||||
|
|
|
|||
27
Examples/test-suite/javascript/nspace_extend_runme.js
Normal file
27
Examples/test-suite/javascript/nspace_extend_runme.js
Normal 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);
|
||||
77
Examples/test-suite/javascript/nspace_runme.js
Normal file
77
Examples/test-suite/javascript/nspace_runme.js
Normal 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();
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue