diff --git a/lib/src/markdown_processor.dart b/lib/src/markdown_processor.dart index 5cfabf5df5..12a66dec2c 100644 --- a/lib/src/markdown_processor.dart +++ b/lib/src/markdown_processor.dart @@ -446,15 +446,22 @@ class _MarkdownCommentReference { // If a result is accessible in this library, prefer that. _reducePreferResultsAccessibleInSameLibrary, // This may refer to an element with the same name in multiple libraries - // in an external package, e.g. Matrix4 in vector_math and vector_math_64. - // Disambiguate by attempting to figure out which of them our package - // is actually using by checking the import/export graph. + // in an external package, e.g. Matrix4 in vector_math and + // vector_math_64. Disambiguate by attempting to figure out which of + // them our package is actually using by checking the import/export + // graph. _reducePreferLibrariesInLocalImportExportGraph, - // If a result's fully qualified name has pieces of the comment reference, - // prefer that. + // If a result's fully qualified name has pieces of the comment + // reference, prefer that. _reducePreferReferencesIncludingFullyQualifiedName, - // Prefer the Dart analyzer's resolution of comment references. We can't - // start from this because of the differences in Dartdoc canonicalization. + // If the reference is indicated to be a constructor, prefer + // constructors. This is not as generic as it sounds; very few naming + // conflicts are allowed, but an instance field is allowed to have the + // same name as a named constructor. + _reducePreferConstructorViaIndicators, + // Prefer the Dart analyzer's resolution of comment references. We + // can't start from this because of the differences in Dartdoc + // canonicalization. _reducePreferAnalyzerResolution, ]) { reduceMethod(); @@ -497,6 +504,13 @@ class _MarkdownCommentReference { } } + void _reducePreferConstructorViaIndicators() { + if (codeRef.contains(_constructorIndicationPattern) && + codeRefChompedParts.length >= 2) { + results.removeWhere((r) => r is! Constructor); + } + } + void _reducePreferReferencesIncludingFullyQualifiedName() { var startName = '${element.fullyQualifiedName}.'; var realName = '${element.fullyQualifiedName}.${codeRefChomped}'; diff --git a/test/end2end/model_test.dart b/test/end2end/model_test.dart index d77010055c..5b28c259c1 100644 --- a/test/end2end/model_test.dart +++ b/test/end2end/model_test.dart @@ -1336,6 +1336,17 @@ void main() { 'null-checked variable myNumber!')); }); + test('reference to constructor named the same as a field', () { + var FieldAndCtorWithSameName = exLibrary.classes + .firstWhere((c) => c.name == 'FieldAndCtorWithSameName'); + var comment = FieldAndCtorWithSameName.documentationAsHtml; + expect( + comment, + contains('Reference to ' + '' + 'FieldAndCtorWithSameName.named()')); + }); + test('reference to class from another library', () { var comment = superAwesomeClass.documentationAsHtml; expect( @@ -1641,7 +1652,7 @@ void main() { }); test('correctly finds all the classes', () { - expect(classes, hasLength(35)); + expect(classes, hasLength(36)); }); test('abstract', () { diff --git a/testing/test_package/lib/example.dart b/testing/test_package/lib/example.dart index 11c9c9b520..ce8ae82949 100644 --- a/testing/test_package/lib/example.dart +++ b/testing/test_package/lib/example.dart @@ -262,6 +262,13 @@ class B extends Apple with Cat { /// Reference to nullable type: [Apple?] and null-checked variable [myNumber!]. class RefsWithQsAndBangs {} +/// Reference to [FieldAndCtorWithSameName.named()]. +class FieldAndCtorWithSameName { + FieldAndCtorWithSameName.named(); + + int named; +} + // Do NOT add a doc comment to C. Testing blank comments. abstract class Cat {