Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[sipify] support multiple classes template definition (#52838)
  • Loading branch information
3nids committed Apr 22, 2023
1 parent db6cef0 commit 8ce4718
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 11 deletions.
50 changes: 39 additions & 11 deletions scripts/sipify.pl
Expand Up @@ -897,14 +897,16 @@ sub detect_non_method_member{
}

# class declaration started
# https://regex101.com/r/6FWntP/16
if ( $LINE =~ m/^(\s*(class))\s+([A-Z0-9_]+_EXPORT\s+)?(Q_DECL_DEPRECATED\s+)?(?<classname>\w+)(?<domain>\s*\:\s*(public|protected|private)\s+\w+(< *(\w|::)+ *>)?(::\w+(<\w+>)?)*(,\s*(public|protected|private)\s+\w+(< *(\w|::)+ *>)?(::\w+(<\w+>)?)*)*)?(?<annot>\s*\/?\/?\s*SIP_\w+)?\s*?(\/\/.*|(?!;))$/ ){
# https://regex101.com/r/KMQdF5/1 (older versions: https://regex101.com/r/6FWntP/16)
if ( $LINE =~ m/^(\s*(class))\s+([A-Z0-9_]+_EXPORT\s+)?(Q_DECL_DEPRECATED\s+)?(?<classname>\w+)(?<domain>\s*\:\s*(public|protected|private)\s+\w+(< *(\w|::)+ *(, *(\w|::)+ *)*>)?(::\w+(<(\w|::)+(, *(\w|::)+)*>)?)*(,\s*(public|protected|private)\s+\w+(< *(\w|::)+ *(, *(\w|::)+)*>)?(::\w+(<\w+(, *(\w|::)+)?>)?)*)*)?(?<annot>\s*\/?\/?\s*SIP_\w+)?\s*?(\/\/.*|(?!;))$/ ){
dbg_info("class definition started");
push @ACCESS, PUBLIC;
push @EXPORTED, 0;
push @GLOB_BRACKET_NESTING_IDX, 0;
my @template_inheritance_template = ();
my @template_inheritance_class = ();
my @template_inheritance_class1 = ();
my @template_inheritance_class2 = ();
my @template_inheritance_class3 = ();
do {no warnings 'uninitialized';
push @CLASSNAME, $+{classname};
if ($#CLASSNAME == 0){
Expand All @@ -927,14 +929,23 @@ sub detect_non_method_member{
$m =~ s/public +(\w+, *)*(Ui::\w+,? *)+//g; # remove Ui::xxx public inheritance as the namespace is causing troubles
$m =~ s/public +//g;
$m =~ s/[,:]?\s*private +\w+(::\w+)?//g;

# detect template based inheritance
while ($m =~ /[,:]\s+((?!QList)\w+)< *((\w|::)+) *>/g){
# https://regex101.com/r/9LGhyy/1
while ($m =~ /[,:]\s+(?<tpl>(?!QList)\w+)< *(?<cls1>(\w|::)+) *(, *(?<cls2>(\w|::)+)? *(, *(?<cls3>(\w|::)+)? *)?)? *>/g){
dbg_info("template class");
push @template_inheritance_template, $1;
push @template_inheritance_class, $2;
push @template_inheritance_template, $+{tpl};
push @template_inheritance_class1, $+{cls1};
push @template_inheritance_class2, $+{cls2} // "";
push @template_inheritance_class3, $+{cls3} // "";
# dbg_info("template classes (max 3): $+{cls1} $+{cls2} $+{cls3}");
}
$m =~ s/(\b(?!QList)\w+)< *((?:\w|::)+) *>/$1${2}Base/g; # use the typeded as template inheritance
$m =~ s/(\w+)< *((?:\w|::)+) *>//g; # remove remaining templates
dbg_info("domain: $m");
do {no warnings 'uninitialized';
# https://regex101.com/r/nOLg2r/1
$m =~ s/\b(?<tpl>(?!QList)\w+)< *(?<cls1>(\w|::)+) *(, *(?<cls2>(\w|::)+)? *(, *(?<cls3>(\w|::)+)? *)?)? *>/$+{tpl}$+{cls1}$+{cls2}$+{cls3}Base/g; # use the typeded as template inheritance
};
$m =~ s/(\w+)< *(?:\w|::)+ *>//g; # remove remaining templates
$m =~ s/([:,])\s*,/$1/g;
$m =~ s/(\s*[:,])?\s*$//;
$LINE .= $m;
Expand All @@ -956,16 +967,30 @@ sub detect_non_method_member{
# see https://www.riverbankcomputing.com/pipermail/pyqt/2015-May/035893.html
while ( @template_inheritance_template ) {
my $tpl = pop @template_inheritance_template;
my $cls = pop @template_inheritance_class;
$LINE = "\ntypedef $tpl<$cls> ${tpl}${cls}Base;\n\n$LINE";
my $cls1 = pop @template_inheritance_class1;
my $cls2 = pop @template_inheritance_class2;
my $cls3 = pop @template_inheritance_class3;
if ( $cls2 eq ""){
$LINE = "\ntypedef $tpl<$cls1> ${tpl}${cls1}Base;\n\n$LINE";
} elsif ( $cls3 eq ""){
$LINE = "\ntypedef $tpl<$cls1,$cls2> ${tpl}${cls1}${cls2}Base;\n\n$LINE";
} else {
$LINE = "\ntypedef $tpl<$cls1,$cls2,$cls3> ${tpl}${cls1}${cls2}${cls3}Base;\n\n$LINE";
}
if ( not $tpl ~~ @DECLARED_CLASSES ){
my $tpl_header = lc $tpl . ".h";
if ( exists $SIP_CONFIG->{class_headerfile}->{$tpl} ){
$tpl_header = $SIP_CONFIG->{class_headerfile}->{$tpl};
}
$LINE .= "\n#include \"" . $tpl_header . "\"";
}
$LINE .= "\ntypedef $tpl<$cls> ${tpl}${cls}Base;";
if ( $cls2 eq ""){
$LINE .= "\ntypedef $tpl<$cls1> ${tpl}${cls1}Base;";
} elsif ( $cls3 eq ""){
$LINE .= "\ntypedef $tpl<$cls1,$cls2> ${tpl}${cls1}${cls2}Base;";
} else {
$LINE .= "\ntypedef $tpl<$cls1,$cls2,$cls3> ${tpl}${cls1}${cls2}${cls3}Base;";
}
}
if ( PRIVATE ~~ @ACCESS && $#ACCESS != 0){
# do not write anything in PRIVATE context and not top level
Expand Down Expand Up @@ -1194,6 +1219,9 @@ sub detect_non_method_member{
# keyword fixes
do {no warnings 'uninitialized';
$LINE =~ s/^(\s*template\s*<)(?:class|typename) (\w+>)(.*)$/$1$2$3/;
$LINE =~ s/^(\s*template\s*<)(?:class|typename) (\w+) *, *(?:class|typename) (\w+>)(.*)$/$1$2,$3$4/;
# https://regex101.com/r/EB1mpx/1
$LINE =~ s/^(\s*template\s*<)(?:class|typename) (\w+) *, *(?:class|typename) (\w+) *, *(?:class|typename) (\w+>)(.*)$/$1$2,$3,$4$5/;
$LINE =~ s/\s*\boverride\b//;
$LINE =~ s/\s*\bSIP_MAKE_PRIVATE\b//;
$LINE =~ s/\s*\bFINAL\b/ \${SIP_FINAL}/;
Expand Down
12 changes: 12 additions & 0 deletions tests/code_layout/sipify/sipifyheader.expected.sip
Expand Up @@ -444,6 +444,18 @@ class TemplateInheritance5 : SomethingElse
%End
}

typedef YourSuperTemplate<Abc,Def,Ghi> YourSuperTemplateAbcDefGhiBase;

class TemplateInheritance6 : SomethingElse, YourSuperTemplateAbcDefGhiBase
{

%TypeHeaderCode
#include "sipifyheader.h"
#include "yoursupertemplate.h"
typedef YourSuperTemplate<Abc,Def,Ghi> YourSuperTemplateAbcDefGhiBase;
%End
}


/************************************************************************
* This file has been generated automatically from *
Expand Down
3 changes: 3 additions & 0 deletions tests/code_layout/sipify/sipifyheader.h
Expand Up @@ -523,6 +523,9 @@ class CORE_EXPORT TemplateInheritance4 : public SomethingElse1, public QList<Som
class CORE_EXPORT TemplateInheritance5 : public SomethingElse, public QList<Something>
{
}
class CORE_EXPORT TemplateInheritance6 : public SomethingElse, public YourSuperTemplate<Abc, Def, Ghi>
{
}


#endif

0 comments on commit 8ce4718

Please sign in to comment.