@@ -54,9 +54,16 @@ final _versionedTizenLibraryPathRegExp = RegExp(
5454);
5555final _listRegExp = RegExp (r'^\d+\.\s' );
5656final _topLevelDeclarationRegExp = RegExp (
57- r'^(typedef|(?:abstract|final)\s+class|class|enum)\s+' ,
57+ r'^(typedef|(?:abstract|final|base)?\s*class|class|enum|extension|const|final|var|late)\s+' ,
58+ );
59+ final _primaryNativeClassRegExp = RegExp (r'^(?:final\s+)?class\s+Tizen[0-9]+Native\b' );
60+ final _moduleBindingPathRegExp = RegExp (
61+ r'(^|[\\/])lib[\\/]src[\\/]bindings[\\/](\d+\.\d+)[\\/]generated_bindings_(\w+)\.dart$' ,
62+ );
63+ final _mainClassRegExp = RegExp (r'^class\s+(Tizen\d+\w+)\b' );
64+ final _alwaysHideFilesRegExp = RegExp (
65+ r'(^|[\\/])lib[\\/]src[\\/](extensions|bindings[\\/]\d+\.\d+[\\/]generated_symbols)\.dart$' ,
5866);
59- final _primaryNativeClassRegExp = RegExp (r'^class\s+Tizen[0-9]+Native\b' );
6067final _publicTopLevelGetterRegExp = RegExp (
6168 r'^[A-Za-z][A-Za-z0-9_<>,?. ]+\s+get\s+[A-Za-z][A-Za-z0-9_]*\b' ,
6269);
@@ -175,13 +182,17 @@ void main(List<String> args) {
175182 for (final entry in bindingDir.listSync ()) {
176183 if (entry is File ) {
177184 final fileName = p.basename (entry.path);
178- if (fileName.startsWith ('generated_bindings' ) &&
179- fileName.endsWith ('.dart' )) {
185+ if (fileName.endsWith ('.dart' )) {
180186 pathsToProcess.add (entry.path);
181187 }
182188 }
183189 }
184- } else {
190+ }
191+ final extensionsFile = File ('lib/src/extensions.dart' );
192+ if (extensionsFile.existsSync ()) {
193+ pathsToProcess.add (extensionsFile.path);
194+ }
195+ if (pathsToProcess.isEmpty) {
185196 stderr.writeln (
186197 'Expected a Dart file path or version (e.g. "6.0"), got: $arg ' ,
187198 );
@@ -220,18 +231,34 @@ List<String> convertDoxygenDocCommentLines(List<String> docLines) {
220231
221232/// Returns true when a doc-comment block contains recognized Doxygen markers.
222233bool looksLikeDoxygenDocCommentBlock (List <String > docLines) {
234+ var hasDoxygenTags = false ;
235+
223236 for (final line in docLines) {
224237 final stripped = _stripGeneratedDocLine (line).trim ();
238+
239+ // If it already looks like converted Dartdoc, don't process it again.
240+ if (stripped.startsWith ('**Since Tizen:**' ) ||
241+ stripped.startsWith ('**Parameters:**' ) ||
242+ stripped.startsWith ('**Returns:**' ) ||
243+ stripped.startsWith ('**Remarks:**' ) ||
244+ stripped.startsWith ('**Return values:**' ) ||
245+ stripped.startsWith ('**See also:**' ) ||
246+ stripped.startsWith ('**Example:**' ) ||
247+ stripped.contains ('{@nodoc}' ) ||
248+ stripped.contains ('{@category' )) {
249+ return false ;
250+ }
251+
225252 if (line.trim ().startsWith ('<' ) ||
226253 _doxygenTagRegExp.hasMatch (stripped) ||
227254 _inlineDoxygenTagRegExp.hasMatch (stripped) ||
228- _squareBracketLiteralRegExp .hasMatch (stripped) ||
255+ RegExp ( r'\[(in|out|in,out)\]' ) .hasMatch (stripped) ||
229256 stripped.contains ('```[' )) {
230- return true ;
257+ hasDoxygenTags = true ;
231258 }
232259 }
233260
234- return false ;
261+ return hasDoxygenTags ;
235262}
236263
237264/// Converts all recognized Doxygen-style `///` blocks in a Dart source string.
@@ -274,11 +301,15 @@ String convertDoxygenCommentsInDartSource(String source, {String? path}) {
274301 output.addAll (converted.map ((commentLine) => '$indent $commentLine ' ));
275302 }
276303
277- final annotatedOutput = _shouldHideTopLevelGeneratedBindingsDeclarations (path)
278- ? _annotateGeneratedBindingsTopLevelDeclarations (output)
279- : _shouldHideVersionedTizenLibraryGetters (path)
280- ? _annotateVersionedTizenLibraryGetters (output)
281- : output;
304+ final annotatedOutput = _isModuleBindingFile (path)
305+ ? _annotateModuleBindingDeclarations (output, path)
306+ : _isAlwaysHideFile (path)
307+ ? _annotateAllAsNodoc (output)
308+ : _shouldHideTopLevelGeneratedBindingsDeclarations (path)
309+ ? _annotateGeneratedBindingsTopLevelDeclarations (output)
310+ : _shouldHideVersionedTizenLibraryGetters (path)
311+ ? _annotateVersionedTizenLibraryGetters (output)
312+ : output;
282313 final normalizedOutput = _rewriteVersionedTizenLibraryName (
283314 annotatedOutput,
284315 path,
@@ -325,6 +356,103 @@ bool _shouldHideVersionedTizenLibraryGetters(String? path) {
325356 return _versionedTizenLibraryPathRegExp.hasMatch (path);
326357}
327358
359+ bool _isModuleBindingFile (String ? path) {
360+ if (path == null ) {
361+ return false ;
362+ }
363+ return _moduleBindingPathRegExp.hasMatch (path);
364+ }
365+
366+ List <String > _annotateModuleBindingDeclarations (
367+ List <String > lines,
368+ String ? path,
369+ ) {
370+ if (path == null ) {
371+ return lines;
372+ }
373+
374+ final match = _moduleBindingPathRegExp.firstMatch (path);
375+ if (match == null ) {
376+ return lines;
377+ }
378+
379+ final version = match.group (2 )! ;
380+ final moduleName = match.group (3 )! ;
381+ final versionId = version.replaceAll ('.' , '_' );
382+
383+ String ? mainClassName;
384+ for (final line in lines) {
385+ final classMatch = _mainClassRegExp.firstMatch (line);
386+ if (classMatch != null ) {
387+ mainClassName = classMatch.group (1 );
388+ break ;
389+ }
390+ }
391+
392+ if (mainClassName == null ) {
393+ return lines;
394+ }
395+
396+ final categoryTizen = '$version /tizen' ;
397+ final output = < String > [];
398+
399+ // Add library directive if missing
400+ if (! lines.any ((l) => l.trim ().startsWith ('library ' ))) {
401+ output.add ('/// {@category $categoryTizen }' );
402+ output.add ('library tizen_interop_$versionId .$moduleName ;' );
403+ output.add ('' );
404+ }
405+
406+ for (final line in lines) {
407+ final trimmed = line.trimLeft ();
408+ final isTopLevelLine = trimmed == line;
409+
410+ if (isTopLevelLine &&
411+ _topLevelDeclarationRegExp.hasMatch (trimmed) &&
412+ ! _primaryNativeClassRegExp.hasMatch (trimmed)) {
413+ final isMainClass = _mainClassRegExp.hasMatch (trimmed);
414+
415+ if (isMainClass) {
416+ if (output.isEmpty ||
417+ ! output.last.trim ().contains ('{@category $categoryTizen }' )) {
418+ output.add ('/// {@category $categoryTizen }' );
419+ }
420+ } else {
421+ if (output.isEmpty || ! output.last.trim ().contains ('{@nodoc}' )) {
422+ output.add ('/// {@nodoc}' );
423+ }
424+ }
425+ }
426+
427+ output.add (line);
428+ }
429+
430+ return output;
431+ }
432+
433+ bool _isAlwaysHideFile (String ? path) {
434+ if (path == null ) {
435+ return false ;
436+ }
437+ return _alwaysHideFilesRegExp.hasMatch (path);
438+ }
439+
440+ List <String > _annotateAllAsNodoc (List <String > lines) {
441+ final output = < String > [];
442+ for (final line in lines) {
443+ final trimmed = line.trimLeft ();
444+ final isTopLevelLine = trimmed == line;
445+
446+ if (isTopLevelLine && _topLevelDeclarationRegExp.hasMatch (trimmed)) {
447+ if (output.isEmpty || ! output.last.trim ().contains ('{@nodoc}' )) {
448+ output.add ('/// {@nodoc}' );
449+ }
450+ }
451+ output.add (line);
452+ }
453+ return output;
454+ }
455+
328456List <String > _annotateGeneratedBindingsTopLevelDeclarations (
329457 List <String > lines,
330458) {
@@ -1066,9 +1194,17 @@ String _mergeDocText(String current, String next) {
10661194 final nextTrimmed = next.trimLeft ();
10671195 if (nextTrimmed.startsWith ('- ' ) ||
10681196 nextTrimmed.startsWith ('* ' ) ||
1197+ nextTrimmed.startsWith ('```' ) ||
1198+ nextTrimmed.startsWith ('< ' ) ||
1199+ nextTrimmed.startsWith ('Privilege :' ) ||
1200+ nextTrimmed.startsWith ('{@' ) ||
1201+ (nextTrimmed.startsWith ('**' ) && nextTrimmed.contains (':**' )) ||
10691202 _listRegExp.hasMatch (nextTrimmed)) {
10701203 return '$current \n $next ' ;
10711204 }
1205+ if (current.endsWith ('\n ' ) || current.trimRight ().endsWith ('<' )) {
1206+ return '$current \n $next ' ;
1207+ }
10721208 return '$current $next ' ;
10731209}
10741210
0 commit comments