diff options
author | Xavier Claessens <xclaesse@gmail.com> | 2019-07-17 15:54:27 +0000 |
---|---|---|
committer | Xavier Claessens <xclaesse@gmail.com> | 2019-07-17 15:54:27 +0000 |
commit | 3a87f89913ddc8e33977d15388cb77c869eaf15c (patch) | |
tree | 96ce0cf6b8ec1a687c09eae767b38218898e25e4 | |
parent | 53295ae10e2e3160480b6d0e52cc0602b4ca4e7a (diff) | |
parent | c042912cac003c2077ac6353b8a84b3ddd00d1bf (diff) | |
download | gtk-doc-3a87f89913ddc8e33977d15388cb77c869eaf15c.tar.gz |
Merge branch 'glib-deprecated' into 'master'
Add support for GLIB_DEPRECATED_ decorators
See merge request GNOME/gtk-doc!32
-rw-r--r-- | gtkdoc/scan.py | 47 | ||||
-rw-r--r-- | tests/bugs/docs/Makefile.am | 2 | ||||
-rw-r--r-- | tests/bugs/docs/meson.build | 2 | ||||
-rw-r--r-- | tests/bugs/docs/tester-sections.txt | 6 | ||||
-rw-r--r-- | tests/bugs/src/tester.h | 63 | ||||
-rwxr-xr-x | tests/scan.py | 67 |
6 files changed, 172 insertions, 15 deletions
diff --git a/gtkdoc/scan.py b/gtkdoc/scan.py index 7da060f..ae4f866 100644 --- a/gtkdoc/scan.py +++ b/gtkdoc/scan.py @@ -81,14 +81,10 @@ CLINE_MATCHER = [ r"""^\s*enum\s+ _?(\w+) # 1: name \s+\{""", re.VERBOSE), - re.compile(r'^\s*typedef\s+enum\s+_?(\w+)\s+\1\s*;'), + None, # in ScanHeaderContent() re.compile(r'^\s*typedef\s+enum'), # 8-11: STRUCTS AND UNIONS - re.compile( - r"""^\s*typedef\s+ - (struct|union)\s+ # 1: struct/union - _(\w+) # 2: name - \s+\2\s*;""", re.VERBOSE), + None, # in ScanHeaderContent() re.compile(r'^\s*(?:struct|union)\s+_(\w+)\s*;'), re.compile( r"""^\s* @@ -132,7 +128,7 @@ CLINE_MATCHER = [ # 18-21: FUNCTIONS None, # in ScanHeaderContent() None, # in ScanHeaderContent() - re.compile(r'^\s*([A-Za-z]\w*)\s*\('), + re.compile(r'^\s*\(?([A-Za-z]\w*)\)?\s*\('), re.compile(r'^\s*\('), # 22-23: STRUCTS re.compile(r'^\s*struct\s+_?(\w+)\s*\*'), @@ -377,8 +373,10 @@ def ScanHeaderContent(input_lines, decl_list, get_types, options): # avoid generating regex with |'' (matching no string) ignore_decorators = '' + optional_decorators_regex = '' if options.ignore_decorators: - ignore_decorators = '|' + options.ignore_decorators + ignore_decorators = '|' + options.ignore_decorators.replace('()', '\(\w*\)') + optional_decorators_regex = '(?:\s+(?:%s))?' % ignore_decorators[1:] # FUNCTION POINTER VARIABLES CLINE_MATCHER[4] = re.compile( @@ -389,6 +387,14 @@ def ScanHeaderContent(input_lines, decl_list, get_types, options): \(\*\s* (\w+) # 4: name \)\s*\(""" % ignore_decorators, re.VERBOSE) + + CLINE_MATCHER[6] = re.compile(r'^\s*typedef\s+enum\s+_?(\w+)\s+\1%s\s*;' % optional_decorators_regex) + CLINE_MATCHER[8] = re.compile( + r"""^\s*typedef\s+ + (struct|union)\s+ # 1: struct/union + _(\w+)\s+\2 # 2: name + %s # 3: optional decorator + \s*;""" % optional_decorators_regex, re.VERBOSE) # OTHER TYPEDEFS CLINE_MATCHER[15] = re.compile( r"""^\s* @@ -411,7 +417,7 @@ def ScanHeaderContent(input_lines, decl_list, get_types, options): (?:\b(?:extern|static|inline|G_INLINE_FUNC%s)\s*)* (%s\w+) # 1: return type ([\s*]+(?:\s*(?:\*+|\bconst\b|\bG_CONST_RETURN\b))*)\s* # 2: .. cont' - ([A-Za-z]\w*) # 3: name + \(?([A-Za-z]\w*)\)? # 3: name \s*\(""" % (ignore_decorators, RET_TYPE_MODIFIER), re.VERBOSE) PLINE_MATCHER[2] = re.compile( @@ -882,19 +888,33 @@ def ScanHeaderContent(input_lines, decl_list, get_types, options): in_declaration = '' if in_declaration == 'enum': - em = re.search(r'\}\s*(\w+)?;\s*$', decl) + # Examples: + # "};" + # "} MyEnum;" + # "} MyEnum DEPRECATED_FOR(NewEnum);" + # "} DEPRECATED_FOR(NewEnum);" + em = re.search(r'\n\s*\}\s*(?:(\w+)?%s)?;\s*$' % optional_decorators_regex, decl) if em: if symbol == '': symbol = em.group(1) + # Enums could contain deprecated values and that doesn't mean + # the whole enum is deprecated, so they are ignored when setting + # deprecated_conditional_nest above. Here we can check if the + # _DEPRECATED is between '}' and ';' which would mean the enum + # as a whole is deprecated. + if re.search(r'\n\s*\}.*_DEPRECATED.*;\s*$', decl): + deprecated = '<DEPRECATED/>\n' if AddSymbolToList(slist, symbol): - decl_list.append('<ENUM>\n<NAME>%s</NAME>\n%s%s</ENUM>\n' % (symbol, deprecated, decl)) + stripped_decl = re.sub(optional_decorators_regex, '', decl) + decl_list.append('<ENUM>\n<NAME>%s</NAME>\n%s%s</ENUM>\n' % (symbol, deprecated, stripped_decl)) deprecated_conditional_nest = int(deprecated_conditional_nest) in_declaration = '' # We try to handle nested structs/unions, but unmatched brackets in # comments will cause problems. if in_declaration == 'struct' or in_declaration == 'union': - sm = re.search(r'\n\}\s*(\w*);\s*$', decl) + # Same regex as for enum + sm = re.search(r'\n\}\s*(?:(\w+)?%s)?;\s*$' % optional_decorators_regex, decl) if level <= 1 and sm: if symbol == '': symbol = sm.group(1) @@ -908,8 +928,9 @@ def ScanHeaderContent(input_lines, decl_list, get_types, options): logging.info('Store struct: "%s"', symbol) if AddSymbolToList(slist, symbol): structsym = in_declaration.upper() + stripped_decl = re.sub('(%s)' % optional_decorators_regex, '', decl) decl_list.append('<%s>\n<NAME>%s</NAME>\n%s%s</%s>\n' % - (structsym, symbol, deprecated, decl, structsym)) + (structsym, symbol, deprecated, stripped_decl, structsym)) if symbol in forward_decls: del forward_decls[symbol] deprecated_conditional_nest = int(deprecated_conditional_nest) diff --git a/tests/bugs/docs/Makefile.am b/tests/bugs/docs/Makefile.am index 7e3643c..2f33b00 100644 --- a/tests/bugs/docs/Makefile.am +++ b/tests/bugs/docs/Makefile.am @@ -19,7 +19,7 @@ SCANGOBJ_OPTIONS= # Extra options to supply to gtkdoc-scan. SCAN_OPTIONS=--deprecated-guards="GTKDOC_TESTER_DISABLE_DEPRECATED" \ - --ignore-decorators='GLIB_VAR|GTKDOC_GNUC_CONST|BUG_711598_DEPRECATED_FOR\(.+\)' \ + --ignore-decorators='GLIB_VAR|GTKDOC_GNUC_CONST|BUG_711598_DEPRECATED_FOR()|MY_DEPRECATED_FOR()' \ --rebuild-types # Extra options to supply to gtkdoc-mkdb. diff --git a/tests/bugs/docs/meson.build b/tests/bugs/docs/meson.build index 567fb4f..726cf4d 100644 --- a/tests/bugs/docs/meson.build +++ b/tests/bugs/docs/meson.build @@ -34,7 +34,7 @@ test( '--source-dir=@0@'.format(bugs_test_source_dir), '--ignore-headers=config.h', '--deprecated-guards=GTKDOC_TESTER_DISABLE_DEPRECATED', - '--ignore-decorators=GLIB_VAR|GTKDOC_GNUC_CONST|BUG_711598_DEPRECATED_FOR\(.+\)', + '--ignore-decorators=GLIB_VAR|GTKDOC_GNUC_CONST|BUG_711598_DEPRECATED_FOR()|MY_DEPRECATED_FOR()', '--rebuild-types', ], ) diff --git a/tests/bugs/docs/tester-sections.txt b/tests/bugs/docs/tester-sections.txt index 9e6a5ff..e71d1bd 100644 --- a/tests/bugs/docs/tester-sections.txt +++ b/tests/bugs/docs/tester-sections.txt @@ -12,6 +12,10 @@ Bug512154 Bug644291 Bug000000Scope Bug76 +MyDeprecatedEnum +MyNotDeprecatedEnum +MyDeprecatedStruct +MyNotDeprecatedStruct <SUBSECTION Functions> bug_000000_va1 BUG_000000_VA2 @@ -59,6 +63,7 @@ bug_783420 gst_play_marshal_BUFFER__BOXED BUG_791928 _ +inline_func_with_macro <SUBSECTION Standard> <SUBSECTION Private> GTKDOC_GNUC_CONST @@ -68,4 +73,5 @@ GLIB_DEPRECATED BUG_711598_DEPRECATED_FOR bug_554833_new G_GNUC_NONNULL +MY_DEPRECATED_FOR </SECTION> diff --git a/tests/bugs/src/tester.h b/tests/bugs/src/tester.h index 0940e3e..3ed3fc0 100644 --- a/tests/bugs/src/tester.h +++ b/tests/bugs/src/tester.h @@ -432,4 +432,67 @@ struct _Bug76 }; typedef struct _Bug76 Bug76; +#define MY_DEPRECATED_FOR(val) + +/** + * MyNotDeprecatedEnum: + * @MY_NOT_DEPRECATED_ENUM_VAL1: new value + * + * some description + */ +typedef enum { + MY_NOT_DEPRECATED_ENUM_VAL1, +} MyNotDeprecatedEnum; + +/** + * MyDeprecatedEnum: + * @MY_DEPRECATED_ENUM_VAL1: deprecated, use instead %MY_DEPRECATED_ENUM_VAL2 + * @MY_DEPRECATED_ENUM_VAL2: val2 + * + * some description + * Deprecated: Use #MyNotDeprecatedEnum instead + */ +typedef enum { + MY_DEPRECATED_ENUM_VAL1 MY_DEPRECATED_FOR(MY_DEPRECATED_ENUM_VAL2), + MY_DEPRECATED_ENUM_VAL2, +} MyDeprecatedEnum MY_DEPRECATED_FOR(MyNotDeprecatedEnum); + +/** + * MyDeprecatedStruct: + * + * some description + * Deprecated: Use #MyNotDeprecatedStruct instead + */ +typedef struct _MyDeprecatedStruct MyDeprecatedStruct MY_DEPRECATED_FOR(MyNotDeprecatedStruct); +struct _MyDeprecatedStruct { + /*< private >*/ + guint index; +} MY_DEPRECATED_FOR(MyNotDeprecatedStruct); + +/** + * MyNotDeprecatedStruct: + * + * some description + */ +typedef struct { + /*< private >*/ + guint index_plop; +} MyNotDeprecatedStruct; + +/** + * inline_func_with_macro: + * @obj: arg + * + * GLib has a few inline functions with a macro that has the same name. It puts + * the inline function name into parenthesis to avoid macro expansion. + * See g_set_object(). + */ +static inline gboolean +(inline_func_with_macro) (void *obj) +{ + return TRUE; +} + +#define inline_func_with_macro(obj) + #endif // GTKDOC_TESTER_H diff --git a/tests/scan.py b/tests/scan.py index 57b4603..98fddf7 100755 --- a/tests/scan.py +++ b/tests/scan.py @@ -220,6 +220,39 @@ class ScanHeaderContentEnum(ScanHeaderContentTestCase): header.splitlines(keepends=True)) self.assertDecl('Data', header, slist) + def test_HandleDeprecatedMemberDecorator(self): + header = textwrap.dedent("""\ + typedef enum { + VAL_DEFAULT, + OTHER_VAL MY_DEPRECATED_FOR(VAL_DEFAULT), + } Data;""") + expected = textwrap.dedent("""\ + typedef enum { + VAL_DEFAULT, + OTHER_VAL, + } Data;""") + self.options.ignore_decorators = 'MY_DEPRECATED_FOR()' + slist, doc_comments = self.scanHeaderContent( + header.splitlines(keepends=True)) + self.assertDecl('Data', expected, slist) + + def test_HandleDeprecatedDecorator(self): + header = textwrap.dedent("""\ + typedef enum { + VAL_DEFAULT, + OTHER_VAL, + } Data MY_DEPRECATED_FOR(OtherEnum);""") + expected = textwrap.dedent("""\ + <DEPRECATED/> + typedef enum { + VAL_DEFAULT, + OTHER_VAL, + } Data;""") + self.options.ignore_decorators = 'MY_DEPRECATED_FOR()' + slist, doc_comments = self.scanHeaderContent( + header.splitlines(keepends=True)) + self.assertDecl('Data', expected, slist) + class ScanHeaderContentFunctions(ScanHeaderContentTestCase): """Test parsing of function declarations.""" @@ -364,6 +397,18 @@ class ScanHeaderContentFunctions(ScanHeaderContentTestCase): header.splitlines(keepends=True)) self.assertDecl('func', 'int', 'int a', slist) + @parameterized.expand(INLINE_MODIFIERS) + def test_FindsInlineFunctionWithParenthesisName(self, _, modifier): + header = textwrap.dedent("""\ + %s void + (func) (void) + { + } + """ % modifier) + slist, doc_comments = self.scanHeaderContent( + header.splitlines(keepends=True)) + self.assertDecl('func', 'void', 'void', slist) + class ScanHeaderContentMacros(ScanHeaderContentTestCase): """Test parsing of macro declarations.""" @@ -480,6 +525,28 @@ class ScanHeaderContentStructs(ScanHeaderContentTestCase): header.splitlines(keepends=True)) self.assertIn('<TITLE>GtkdocObject</TITLE>', slist) + def test_DeprecatedDecorator(self): + header = textwrap.dedent("""\ + typedef struct { + int x; + } Data MY_DEPRECATED_FOR(OtherStruct);""") + expected = textwrap.dedent("""\ + <DEPRECATED/> + typedef struct { + int x; + } Data;""") + self.options.ignore_decorators = 'MY_DEPRECATED_FOR()' + slist, doc_comments = self.scanHeaderContent( + header.splitlines(keepends=True)) + self.assertDecl('Data', expected, slist) + + def test_DeprecatedOpaqueStructTypedef(self): + header = 'typedef struct _data data MY_DEPRECATED_FOR(OtherData);' + expected = '<DEPRECATED/>\n' + self.options.ignore_decorators = 'MY_DEPRECATED_FOR()' + slist, doc_comments = self.scanHeaderContent([header]) + self.assertDecl('data', expected, slist) + class ScanHeaderContentUnions(ScanHeaderContentTestCase): """Test parsing of union declarations.""" |