diff --git a/lib/src/render/parameter_renderer.dart b/lib/src/render/parameter_renderer.dart
index 9b938c19c5..f2e5c9f34f 100644
--- a/lib/src/render/parameter_renderer.dart
+++ b/lib/src/render/parameter_renderer.dart
@@ -2,9 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:convert';
+
import 'package:analyzer/dart/element/type.dart';
import 'package:dartdoc/src/element_type.dart';
import 'package:dartdoc/src/model/parameter.dart';
+import 'package:meta/meta.dart' as meta;
/// Render HTML in an extended vertical format using
tag.
class ParameterRendererHtmlList extends ParameterRendererHtml {
@@ -27,8 +30,12 @@ class ParameterRendererHtml extends ParameterRenderer {
@override
String covariant(String covariant) => '$covariant';
@override
- String defaultValue(String defaultValue) =>
- '$defaultValue';
+ String defaultValue(String defaultValue) {
+ var escaped =
+ const HtmlEscape(HtmlEscapeMode.unknown).convert(defaultValue);
+ return '$escaped';
+ }
+
@override
String parameter(String parameter, String htmlId) =>
'$parameter';
@@ -93,34 +100,38 @@ abstract class ParameterRenderer {
var positional = '', optional = '', named = '';
if (positionalParams.isNotEmpty) {
positional = _linkedParameterSublist(positionalParams,
- optionalPositionalParams.isNotEmpty || namedParams.isNotEmpty,
- showMetadata: showMetadata, showNames: showNames);
+ trailingComma:
+ optionalPositionalParams.isNotEmpty || namedParams.isNotEmpty,
+ showMetadata: showMetadata,
+ showNames: showNames);
}
if (optionalPositionalParams.isNotEmpty) {
- optional = _linkedParameterSublist(
- optionalPositionalParams, namedParams.isNotEmpty,
+ optional = _linkedParameterSublist(optionalPositionalParams,
+ trailingComma: namedParams.isNotEmpty,
openBracket: '[',
closeBracket: ']',
showMetadata: showMetadata,
showNames: showNames);
}
if (namedParams.isNotEmpty) {
- named = _linkedParameterSublist(namedParams, false,
+ named = _linkedParameterSublist(namedParams,
+ trailingComma: false,
openBracket: '{',
closeBracket: '}',
showMetadata: showMetadata,
showNames: showNames);
}
- return (orderedList(positional + optional + named));
+ return orderedList(positional + optional + named);
}
- String _linkedParameterSublist(List parameters, bool trailingComma,
- {String openBracket = '',
+ String _linkedParameterSublist(List parameters,
+ {@meta.required bool trailingComma,
+ String openBracket = '',
String closeBracket = '',
showMetadata = true,
showNames = true}) {
var builder = StringBuffer();
- parameters.forEach((p) {
+ for (var p in parameters) {
var prefix = '';
var suffix = '';
if (identical(p, parameters.first)) {
@@ -136,7 +147,7 @@ abstract class ParameterRenderer {
_renderParam(p, showMetadata: showMetadata, showNames: showNames);
builder.write(
listItem(parameter(prefix + renderedParam + suffix, p.htmlId)));
- });
+ }
return builder.toString();
}
diff --git a/test/model_test.dart b/test/model_test.dart
index 90baabe686..4fcc7fabea 100644
--- a/test/model_test.dart
+++ b/test/model_test.dart
@@ -2273,6 +2273,17 @@ void main() {
expect(topLevelFunction.documentation, contains("['hello from dart']"));
});
+ test('escapes HTML in default values', () {
+ var topLevelFunction2 = fakeLibrary.functions
+ .firstWhere((f) => f.name == 'topLevelFunction2');
+
+ expect(
+ topLevelFunction2.linkedParamsLines,
+ contains('p3 = '
+ 'const <String, int>{}'
+ ']'));
+ });
+
test('has source code', () {
expect(topLevelFunction.sourceCode, startsWith('@deprecated'));
expect(topLevelFunction.sourceCode, endsWith('''
diff --git a/testing/test_package/lib/fake.dart b/testing/test_package/lib/fake.dart
index 22b1a1d73f..380bcdf483 100644
--- a/testing/test_package/lib/fake.dart
+++ b/testing/test_package/lib/fake.dart
@@ -737,6 +737,9 @@ String topLevelFunction(int param1, bool param2, Cool coolBeans,
return null;
}
+void topLevelFunction2(int p1, bool p2,
+ [Map p3 = const {}]) {}
+
/// A single optional positional param, no type annotation, no default value.
@greatAnnotation
void onlyPositionalWithNoDefaultNoType([@greatestAnnotation anything]) {}