Skip to content

Commit 187ac31

Browse files
authored
Escape type parameters inside comment references (#1740)
* Escape type parameters and other things inside comment references * Rebuild package docs
1 parent 5b2304e commit 187ac31

File tree

4 files changed

+29
-14
lines changed

4 files changed

+29
-14
lines changed

lib/src/markdown_processor.dart

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,8 @@ final RegExp _hide_schemes = new RegExp('^(http|https)://');
154154

155155
class MatchingLinkResult {
156156
final ModelElement element;
157-
final String label;
158157
final bool warn;
159-
MatchingLinkResult(this.element, this.label, {this.warn: true});
158+
MatchingLinkResult(this.element, {this.warn: true});
160159
}
161160

162161
class IterableBlockParser extends md.BlockParser {
@@ -244,13 +243,12 @@ MatchingLinkResult _getMatchingLinkElement(
244243
// By debugging inspection, it seems correct to not warn when we don't have
245244
// CommentReferences; there's actually nothing that needs resolving in
246245
// that case.
247-
if (commentRefs == null)
248-
return new MatchingLinkResult(null, null, warn: false);
246+
if (commentRefs == null) return new MatchingLinkResult(null, warn: false);
249247

250248
if (!codeRef.contains(isConstructor) &&
251249
codeRef.contains(notARealDocReference)) {
252250
// Don't waste our time on things we won't ever find.
253-
return new MatchingLinkResult(null, null, warn: false);
251+
return new MatchingLinkResult(null, warn: false);
254252
}
255253

256254
ModelElement refModelElement;
@@ -283,20 +281,20 @@ MatchingLinkResult _getMatchingLinkElement(
283281
// TODO(jcollins-g): remove squelching of non-canonical warnings here
284282
// once we no longer process full markdown for
285283
// oneLineDocs (#1417)
286-
return new MatchingLinkResult(null, null, warn: element.isCanonical);
284+
return new MatchingLinkResult(null, warn: element.isCanonical);
287285
}
288286

289287
// Ignore all parameters.
290288
if (refModelElement is Parameter || refModelElement is TypeParameter)
291-
return new MatchingLinkResult(null, null, warn: false);
289+
return new MatchingLinkResult(null, warn: false);
292290

293291
// There have been places in the code which helpfully cache entities
294292
// regardless of what package they are associated with. This assert
295293
// will protect us from reintroducing that.
296294
assert(refModelElement == null ||
297295
refModelElement.packageGraph == element.packageGraph);
298296
if (refModelElement != null) {
299-
return new MatchingLinkResult(refModelElement, null);
297+
return new MatchingLinkResult(refModelElement);
300298
}
301299
// From this point on, we haven't been able to find a canonical ModelElement.
302300
if (!refModelElement.isCanonical) {
@@ -306,15 +304,15 @@ MatchingLinkResult _getMatchingLinkElement(
306304
}
307305
// Don't warn about doc references because that's covered by the no
308306
// canonical library found message.
309-
return new MatchingLinkResult(null, null, warn: false);
307+
return new MatchingLinkResult(null, warn: false);
310308
}
311309
// We should never get here unless there's a bug in findCanonicalModelElementFor.
312310
// findCanonicalModelElementFor(searchElement, preferredClass: preferredClass)
313311
// should only return null if ModelElement.from(searchElement, refLibrary)
314312
// would return a non-canonical element. However, outside of checked mode,
315313
// at least we have a canonical element, so proceed.
316314
assert(false);
317-
return new MatchingLinkResult(refModelElement, null);
315+
return new MatchingLinkResult(refModelElement);
318316
}
319317

320318
/// Given a set of commentRefs, return the one whose name matches the codeRef.
@@ -725,7 +723,6 @@ String _linkDocReference(
725723
MatchingLinkResult result;
726724
result = _getMatchingLinkElement(codeRef, warnable, commentRefs);
727725
final ModelElement linkedElement = result.element;
728-
final String label = result.label ?? codeRef;
729726
if (linkedElement != null) {
730727
var classContent = '';
731728
if (linkedElement.isDeprecated) {
@@ -734,16 +731,16 @@ String _linkDocReference(
734731
// This would be linkedElement.linkedName, but link bodies are slightly
735732
// different for doc references.
736733
if (linkedElement.href == null) {
737-
return '<code>${htmlEscape.convert(label)}</code>';
734+
return '<code>${htmlEscape.convert(codeRef)}</code>';
738735
} else {
739-
return '<a ${classContent}href="${linkedElement.href}">$label</a>';
736+
return '<a ${classContent}href="${linkedElement.href}">${htmlEscape.convert(codeRef)}</a>';
740737
}
741738
} else {
742739
if (result.warn) {
743740
warnable.warn(PackageWarning.unresolvedDocReference,
744741
message: codeRef, referredFrom: warnable.documentationFrom);
745742
}
746-
return '<code>${htmlEscape.convert(label)}</code>';
743+
return '<code>${htmlEscape.convert(codeRef)}</code>';
747744
}
748745
}
749746

test/model_test.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,18 @@ void main() {
927927
contains(
928928
'<a href="fake/NAME_SINGLEUNDERSCORE-constant.html">NAME_SINGLEUNDERSCORE</a>'));
929929
});
930+
931+
test('correctly escapes type parameters in links', () {
932+
expect(
933+
docsAsHtml,
934+
contains(
935+
'<a href="fake/ExtraSpecialList-class.html">ExtraSpecialList&lt;Object&gt;</a>'));
936+
});
937+
938+
test('correctly escapes type parameters in broken links', () {
939+
expect(docsAsHtml,
940+
contains('<code>ThisIsNotHereNoWay&lt;MyType&gt;</code>'));
941+
});
930942
});
931943

932944
test('multi-underscore names in brackets do not become italicized', () {

testing/test_package/lib/fake.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,10 @@ class BaseForDocComments {
744744
/// Reference to a bracket operator within this class [operator []] xxx
745745
///
746746
/// Reference to a bracket operator in another class [SpecialList.operator []] xxx
747+
///
748+
/// Reference containing a type parameter [ExtraSpecialList<Object>]
749+
///
750+
/// Reference to something that doesn't exist containing a type parameter [ThisIsNotHereNoWay<MyType>]
747751
String doAwesomeStuff(int value) => null;
748752

749753
void anotherMethod() {}

testing/test_package_docs/fake/BaseForDocComments/doAwesomeStuff.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ <h1>doAwesomeStuff method</h1>
9191
the name <a href="two_exports/BaseClass-class.html">BaseClass</a> xx</p>
9292
<p>Reference to a bracket operator within this class <a href="fake/BaseForDocComments/operator_get.html">operator []</a> xxx</p>
9393
<p>Reference to a bracket operator in another class <code>SpecialList.operator []</code> xxx</p>
94+
<p>Reference containing a type parameter <a href="fake/ExtraSpecialList-class.html">ExtraSpecialList&lt;Object&gt;</a></p>
95+
<p>Reference to something that doesn't exist containing a type parameter <code>ThisIsNotHereNoWay&lt;MyType&gt;</code></p>
9496
</section>
9597

9698

0 commit comments

Comments
 (0)