Nested classes support is diversified, depending on the language capability. If the language cannot support nested classes, they will be unconditionally moved to the global namespace. If language module does not override Language::nestedClassesSupport() function, nested classes will be ignored, unless "feature:flatnested" is used.

This commit is contained in:
Vladimir Kalinin 2014-02-02 22:38:13 +04:00
commit 2f3d93e93a
9 changed files with 60 additions and 39 deletions

View file

@ -59,7 +59,7 @@ static int extendmode = 0;
static int compact_default_args = 0;
static int template_reduce = 0;
static int cparse_externc = 0;
int ignore_nested_classes = 0;
/* -----------------------------------------------------------------------------
* Assist Functions
* ----------------------------------------------------------------------------- */
@ -3564,19 +3564,26 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
yyrename = Copy(Getattr($<node>$, "class_rename"));
add_symbols($$);
Delattr($$, "class_rename");
/* but the variable definition in the current scope */
Swig_symbol_setscope(cscope);
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
add_symbols($9);
if (nscope) {
$$ = nscope; /* here we return recreated namespace tower instead of the class itself */
if ($9)
appendSibling($$, $9);
if (currentOuterClass && ignore_nested_classes && !GetFlag($$, "feature:flatnested")) {
SetFlag($$,"feature:ignore");
Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", Getattr($$, "name"));
$$ = 0;
} else {
Delattr($$, "class_rename");
/* but the variable definition in the current scope */
Swig_symbol_setscope(cscope);
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
add_symbols($9);
if (nscope) {
$$ = nscope; /* here we return recreated namespace tower instead of the class itself */
if ($9) {
appendSibling($$, $9);
}
} else if (!SwigType_istemplate(ty) && template_parameters == 0) { /* for tempalte we need the class itself */
$$ = $9;
}
}
else if (!SwigType_istemplate(ty) && template_parameters == 0) /* for tempalte we need the class itself */
$$ = $9;
} else {
Delete(yyrename);
yyrename = 0;
@ -3600,8 +3607,14 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
} else {
yyrename = Copy(Getattr($<node>$, "class_rename"));
add_symbols($$);
add_symbols($9);
Delattr($$, "class_rename");
if (cparse_cplusplus && currentOuterClass && ignore_nested_classes && !GetFlag($$, "feature:flatnested")) {
SetFlag($$,"feature:ignore");
Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", Getattr($$, "name"));
$$ = 0;
} else {
add_symbols($9);
Delattr($$, "class_rename");
}
}
}
Delete(ty);
@ -3734,6 +3747,11 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
add_symbols($$);
add_symbols(n);
Delattr($$, "class_rename");
if (cparse_cplusplus && currentOuterClass && ignore_nested_classes && !GetFlag($$, "feature:flatnested")) {
SetFlag($$,"feature:ignore");
Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", name);
$$ = 0;
}
}else if (cparse_cplusplus)
$$ = 0; /* ignore unnamed structs for C++ */
Delete(unnamed);

View file

@ -76,6 +76,7 @@
#define WARN_PARSE_PRIVATE_INHERIT 309
#define WARN_PARSE_TEMPLATE_REPEAT 310
#define WARN_PARSE_TEMPLATE_PARTIAL 311
#define WARN_PARSE_NESTED_CLASS 312
#define WARN_PARSE_UNDEFINED_EXTERN 313
#define WARN_PARSE_KEYWORD 314
#define WARN_PARSE_USING_UNDEF 315

View file

@ -4288,8 +4288,8 @@ public:
Delete(dirclassname);
}
bool nestedClassesSupported() const {
return true;
NestedClassSupport nestedClassesSupport() const {
return NCS_Full;
}
}; /* class CSHARP */

View file

@ -4607,8 +4607,8 @@ public:
Setattr(n, "director:ctor", class_ctor);
}
bool nestedClassesSupported() const {
return true;
NestedClassSupport nestedClassesSupport() const {
return NCS_Full;
}
}; /* class JAVA */

View file

@ -3441,8 +3441,8 @@ bool Language::extraDirectorProtectedCPPMethodsRequired() const {
return true;
}
bool Language::nestedClassesSupported() const {
return false;
Language::NestedClassSupport Language::nestedClassesSupport() const {
return NCS_Unknown;
}
/* -----------------------------------------------------------------------------
* Language::is_wrapping_class()

View file

@ -49,6 +49,7 @@ int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime
extern "C" {
extern String *ModuleName;
extern int ignore_nested_classes;
}
/* usage string split into multiple parts otherwise string is too big for some compilers */
@ -856,11 +857,6 @@ void SWIG_getoptions(int argc, char *argv[]) {
}
}
static void flatten_nested() {
Swig_feature_set(Swig_cparse_features(), "", 0, "feature:flatnested", "1", 0);
}
int SWIG_main(int argc, char *argv[], Language *l) {
char *c;
@ -905,6 +901,9 @@ int SWIG_main(int argc, char *argv[], Language *l) {
Wrapper_director_mode_set(0);
Wrapper_director_protected_mode_set(1);
// Inform the parser if the nested classes should be ignored unless explicitly told otherwise via feature:flatnested
ignore_nested_classes = l->nestedClassesSupport() == Language::NCS_Unknown ? 1 : 0;
// Create Library search directories
// Check for SWIG_LIB environment variable
@ -1158,10 +1157,6 @@ int SWIG_main(int argc, char *argv[], Language *l) {
fflush(stdout);
}
// add "ignore" directive if nested classes are not supported
if (!lang->nestedClassesSupported())
flatten_nested();
Node *top = Swig_cparse(cpps);
if (dump_top & STAGE1) {

View file

@ -416,7 +416,7 @@ void Swig_nested_name_unnamed_c_structs(Node *n) {
static void remove_outer_class_reference(Node *n) {
for (Node *c = firstChild(n); c; c = nextSibling(c)) {
if (GetFlag(c, "feature:flatnested")) {
if (GetFlag(c, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None) {
Delattr(c, "nested:outer");
remove_outer_class_reference(c);
}
@ -428,7 +428,7 @@ void Swig_nested_process_classes(Node *n) {
while (c) {
Node *next = nextSibling(c);
if (!Getattr(c, "templatetype")) {
if (GetFlag(c, "nested") && GetFlag(c, "feature:flatnested")) {
if (GetFlag(c, "nested") && (GetFlag(c, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None)) {
removeNode(c);
if (!checkAttribute(c, "access", "public"))
SetFlag(c, "feature:ignore");

View file

@ -298,13 +298,19 @@ protected:
virtual bool extraDirectorProtectedCPPMethodsRequired() const;
public:
/* Does target language support nested classes? Default is 'false'. If 'false' is returned, then
%rename("$ignore", %$isnested) statement will be issued at the top, and the nested classes
will be ignored. Note that even if the target language does not support the notion of class
nesting, the language module may nevertheless return true from this function, and use
%feature "flatnested" to move nested classes to the global scope, instead of ignoring them.
enum NestedClassSupport {
NCS_None, // Target language does not have an equivalent to nested classes
NCS_Full, // Target language does have an equivalent to nested classes and is fully implemented
NCS_Unknown // Target language may or may not have an equivalent to nested classes. If it does, it has not been implemented yet.
};
/* Does target language support nested classes? Default is NCS_Unknown.
If NCS_Unknown is returned, then the nested classes will be ignored unless
%feature "flatnested" is applied to them, in which case they will appear in global space.
If the target language does not support the notion of class
nesting, the language module should return NCS_None from this function, and
the nested classes will be moved to the global scope (like implicit global %feature "flatnested").
*/
virtual bool nestedClassesSupported() const;
virtual NestedClassSupport nestedClassesSupport() const;
protected:
/* Identifies if a protected members that are generated when the allprotected option is used.

View file

@ -504,7 +504,8 @@ class TypePass:private Dispatcher {
SwigType_attach_symtab(Getattr(n, "symtab"));
/* Inherit type definitions into the class */
if (name && !(GetFlag(n, "nested") && GetFlag(n, "feature:flatnested") && !checkAttribute(n, "access", "public"))) {
if (name && !(GetFlag(n, "nested") && !checkAttribute(n, "access", "public") &&
(GetFlag(n, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None))) {
cplus_inherit_types(n, 0, nname ? nname : (fname ? fname : name));
}