Escape type parameters inside comment references (#1740)
* Escape type parameters and other things inside comment references
* Rebuild package docs
diff --git a/lib/src/markdown_processor.dart b/lib/src/markdown_processor.dart
index a064053..b2d0685 100644
--- a/lib/src/markdown_processor.dart
+++ b/lib/src/markdown_processor.dart
@@ -154,9 +154,8 @@
class MatchingLinkResult {
final ModelElement element;
- final String label;
final bool warn;
- MatchingLinkResult(this.element, this.label, {this.warn: true});
+ MatchingLinkResult(this.element, {this.warn: true});
}
class IterableBlockParser extends md.BlockParser {
@@ -244,13 +243,12 @@
// By debugging inspection, it seems correct to not warn when we don't have
// CommentReferences; there's actually nothing that needs resolving in
// that case.
- if (commentRefs == null)
- return new MatchingLinkResult(null, null, warn: false);
+ if (commentRefs == null) return new MatchingLinkResult(null, warn: false);
if (!codeRef.contains(isConstructor) &&
codeRef.contains(notARealDocReference)) {
// Don't waste our time on things we won't ever find.
- return new MatchingLinkResult(null, null, warn: false);
+ return new MatchingLinkResult(null, warn: false);
}
ModelElement refModelElement;
@@ -283,12 +281,12 @@
// TODO(jcollins-g): remove squelching of non-canonical warnings here
// once we no longer process full markdown for
// oneLineDocs (#1417)
- return new MatchingLinkResult(null, null, warn: element.isCanonical);
+ return new MatchingLinkResult(null, warn: element.isCanonical);
}
// Ignore all parameters.
if (refModelElement is Parameter || refModelElement is TypeParameter)
- return new MatchingLinkResult(null, null, warn: false);
+ return new MatchingLinkResult(null, warn: false);
// There have been places in the code which helpfully cache entities
// regardless of what package they are associated with. This assert
@@ -296,7 +294,7 @@
assert(refModelElement == null ||
refModelElement.packageGraph == element.packageGraph);
if (refModelElement != null) {
- return new MatchingLinkResult(refModelElement, null);
+ return new MatchingLinkResult(refModelElement);
}
// From this point on, we haven't been able to find a canonical ModelElement.
if (!refModelElement.isCanonical) {
@@ -306,7 +304,7 @@
}
// Don't warn about doc references because that's covered by the no
// canonical library found message.
- return new MatchingLinkResult(null, null, warn: false);
+ return new MatchingLinkResult(null, warn: false);
}
// We should never get here unless there's a bug in findCanonicalModelElementFor.
// findCanonicalModelElementFor(searchElement, preferredClass: preferredClass)
@@ -314,7 +312,7 @@
// would return a non-canonical element. However, outside of checked mode,
// at least we have a canonical element, so proceed.
assert(false);
- return new MatchingLinkResult(refModelElement, null);
+ return new MatchingLinkResult(refModelElement);
}
/// Given a set of commentRefs, return the one whose name matches the codeRef.
@@ -725,7 +723,6 @@
MatchingLinkResult result;
result = _getMatchingLinkElement(codeRef, warnable, commentRefs);
final ModelElement linkedElement = result.element;
- final String label = result.label ?? codeRef;
if (linkedElement != null) {
var classContent = '';
if (linkedElement.isDeprecated) {
@@ -734,16 +731,16 @@
// This would be linkedElement.linkedName, but link bodies are slightly
// different for doc references.
if (linkedElement.href == null) {
- return '<code>${htmlEscape.convert(label)}</code>';
+ return '<code>${htmlEscape.convert(codeRef)}</code>';
} else {
- return '<a ${classContent}href="${linkedElement.href}">$label</a>';
+ return '<a ${classContent}href="${linkedElement.href}">${htmlEscape.convert(codeRef)}</a>';
}
} else {
if (result.warn) {
warnable.warn(PackageWarning.unresolvedDocReference,
message: codeRef, referredFrom: warnable.documentationFrom);
}
- return '<code>${htmlEscape.convert(label)}</code>';
+ return '<code>${htmlEscape.convert(codeRef)}</code>';
}
}
diff --git a/test/model_test.dart b/test/model_test.dart
index 8be534d..0297d4b 100644
--- a/test/model_test.dart
+++ b/test/model_test.dart
@@ -927,6 +927,18 @@
contains(
'<a href="fake/NAME_SINGLEUNDERSCORE-constant.html">NAME_SINGLEUNDERSCORE</a>'));
});
+
+ test('correctly escapes type parameters in links', () {
+ expect(
+ docsAsHtml,
+ contains(
+ '<a href="fake/ExtraSpecialList-class.html">ExtraSpecialList<Object></a>'));
+ });
+
+ test('correctly escapes type parameters in broken links', () {
+ expect(docsAsHtml,
+ contains('<code>ThisIsNotHereNoWay<MyType></code>'));
+ });
});
test('multi-underscore names in brackets do not become italicized', () {
diff --git a/testing/test_package/lib/fake.dart b/testing/test_package/lib/fake.dart
index 84ead50..9a50230 100644
--- a/testing/test_package/lib/fake.dart
+++ b/testing/test_package/lib/fake.dart
@@ -744,6 +744,10 @@
/// Reference to a bracket operator within this class [operator []] xxx
///
/// Reference to a bracket operator in another class [SpecialList.operator []] xxx
+ ///
+ /// Reference containing a type parameter [ExtraSpecialList<Object>]
+ ///
+ /// Reference to something that doesn't exist containing a type parameter [ThisIsNotHereNoWay<MyType>]
String doAwesomeStuff(int value) => null;
void anotherMethod() {}
diff --git a/testing/test_package_docs/fake/BaseForDocComments/doAwesomeStuff.html b/testing/test_package_docs/fake/BaseForDocComments/doAwesomeStuff.html
index 8ea0bfd..35c1672 100644
--- a/testing/test_package_docs/fake/BaseForDocComments/doAwesomeStuff.html
+++ b/testing/test_package_docs/fake/BaseForDocComments/doAwesomeStuff.html
@@ -91,6 +91,8 @@
the name <a href="two_exports/BaseClass-class.html">BaseClass</a> xx</p>
<p>Reference to a bracket operator within this class <a href="fake/BaseForDocComments/operator_get.html">operator []</a> xxx</p>
<p>Reference to a bracket operator in another class <code>SpecialList.operator []</code> xxx</p>
+<p>Reference containing a type parameter <a href="fake/ExtraSpecialList-class.html">ExtraSpecialList<Object></a></p>
+<p>Reference to something that doesn't exist containing a type parameter <code>ThisIsNotHereNoWay<MyType></code></p>
</section>