Skip to content

Commit

Permalink
Format parameters better
Browse files Browse the repository at this point in the history
  • Loading branch information
srawlins committed Mar 19, 2024
1 parent 8b94222 commit 6ef7589
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 62 deletions.
18 changes: 17 additions & 1 deletion lib/resources/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,21 @@ dl dt.callable .name {
padding-inline-start: unset;
}

.parameter-list.single-line {
display: inline;
margin-left: 0;
}

.parameter-list.single-line > li {
display: inline;
}

.parameter-list.single-line > li > .parameter {
display: inline;
margin-left: 0;
text-indent: 0;
}

.signature {
color: var(--main-text-color);
}
Expand Down Expand Up @@ -726,8 +741,9 @@ td {
}

.multi-line-signature .parameter {
margin-left: 24px;
margin-left: 60px;
display: block;
text-indent: -36px;
}

.breadcrumbs {
Expand Down
9 changes: 9 additions & 0 deletions lib/src/model/model_element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -690,11 +690,20 @@ abstract class ModelElement extends Canonicalization
ParameterRenderer get _parameterRendererDetailed =>
const ParameterRendererHtmlList();

/// The list of linked parameters, as inline HTML, including metadata.
///
/// The text does not contain the leading or trailing parentheses.
String get linkedParams => _parameterRenderer.renderLinkedParams(parameters);

/// The list of linked parameters, as block HTML, including metadata.
///
/// The text does not contain the leading or trailing parentheses.
String get linkedParamsLines =>
_parameterRendererDetailed.renderLinkedParams(parameters).trim();

/// The list of linked parameters, as inline HTML, without metadata.
///
/// The text does not contain the leading or trailing parentheses.
String? get linkedParamsNoMetadata =>
_parameterRenderer.renderLinkedParams(parameters, showMetadata: false);

Expand Down
95 changes: 70 additions & 25 deletions lib/src/render/parameter_renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,51 @@ import 'package:dartdoc/src/model/parameter.dart';
class ParameterRendererHtmlList extends ParameterRendererHtml {
const ParameterRendererHtmlList();

@override
bool get isBlock => true;

@override
String listItem(String item) => '<li>$item</li>\n';

@override
// TODO(jcollins-g): consider comma separated lists and more advanced CSS.
String orderedList(String listItems) =>
'<ol class="parameter-list">$listItems</ol>\n';
String orderedList(
String listItems, {
bool multiLine = false,
String trailingText = '',
}) {
var classes = [
'parameter-list',
if (!multiLine) 'single-line',
];
return '<ol class="${classes.join(' ')}"> $listItems</ol>\n$trailingText';
}
}

/// Render HTML suitable for a single, wrapped line.
class ParameterRendererHtml extends ParameterRenderer {
const ParameterRendererHtml();

@override
bool get isBlock => false;

@override
String listItem(String item) => item;

@override
String orderedList(String listItems) => listItems;
String orderedList(
String listItems, {
bool multiLine = false,
String trailingText = '',
}) =>
'$listItems$trailingText';

@override
String annotation(String annotation) => '<span>$annotation</span>';

@override
String covariant(String covariant) => '<span>$covariant</span>';

@override
String defaultValue(String defaultValue) {
var escaped =
Expand All @@ -41,21 +66,30 @@ class ParameterRendererHtml extends ParameterRenderer {
@override
String parameter(String parameter, String id) =>
'<span class="parameter" id="$id">$parameter</span>';

@override
String parameterName(String parameterName) =>
'<span class="parameter-name">$parameterName</span>';

@override
String typeName(String typeName) =>
'<span class="type-annotation">$typeName</span>';

@override
String required(String required) => '<span>$required</span>';
}

abstract class ParameterRenderer {
const ParameterRenderer();

bool get isBlock;

String listItem(String item);
String orderedList(String listItems);
String orderedList(
String listItems, {
bool multiLine = false,
String trailingText = '',
});
String annotation(String annotation);
String covariant(String covariant);
String defaultValue(String defaultValue);
Expand All @@ -66,6 +100,10 @@ abstract class ParameterRenderer {

String renderLinkedParams(List<Parameter> parameters,
{bool showMetadata = true}) {
if (parameters.isEmpty) {
return '';
}

var positionalParams = parameters
.where((Parameter p) => p.isRequiredPositional)
.toList(growable: false);
Expand All @@ -74,63 +112,71 @@ abstract class ParameterRenderer {
.toList(growable: false);
var namedParams =
parameters.where((Parameter p) => p.isNamed).toList(growable: false);
var isMultiLine =
isBlock && (namedParams.isNotEmpty || parameters.length > 3);

var buffer = StringBuffer();
var closingBracket = '';
if (positionalParams.isNotEmpty) {
String trailingText;
if (optionalPositionalParams.isNotEmpty) {
trailingText = ', [';
} else if (namedParams.isNotEmpty) {
trailingText = ', {';
} else if (isMultiLine) {
trailingText = ', ';
} else {
trailingText = '';
}
_renderLinkedParameterSublist(
positionalParams,
buffer,
trailingComma:
optionalPositionalParams.isNotEmpty || namedParams.isNotEmpty,
trailingText: trailingText,
showMetadata: showMetadata,
);
}
if (optionalPositionalParams.isNotEmpty) {
closingBracket = ']';
var trailingText = isMultiLine ? ', ' : '';
_renderLinkedParameterSublist(
optionalPositionalParams,
buffer,
trailingComma: namedParams.isNotEmpty,
openBracket: '[',
closeBracket: ']',
trailingText: trailingText,
showMetadata: showMetadata,
);
}
if (namedParams.isNotEmpty) {
closingBracket = '}';
var trailingText = isMultiLine ? ', ' : '';
_renderLinkedParameterSublist(
namedParams,
buffer,
trailingComma: false,
openBracket: '{',
closeBracket: '}',
trailingText: trailingText,
showMetadata: showMetadata,
);
}
return orderedList(buffer.toString());
return orderedList(
buffer.toString(),
multiLine: isMultiLine,
trailingText: closingBracket,
);
}

void _renderLinkedParameterSublist(
List<Parameter> parameters,
StringBuffer buffer, {
required bool trailingComma,
String openBracket = '',
String closeBracket = '',
String trailingText = '',
bool showMetadata = true,
}) {
for (var p in parameters) {
var prefix = '';
var suffix = '';
if (identical(p, parameters.first)) {
prefix = openBracket;
}
if (identical(p, parameters.last)) {
suffix += closeBracket;
if (trailingComma) suffix += ', ';
suffix = trailingText;
} else {
suffix += ', ';
}
final renderedParameter = _renderParameter(
p,
prefix: prefix,
suffix: suffix,
showMetadata: showMetadata,
);
Expand All @@ -140,11 +186,10 @@ abstract class ParameterRenderer {

String _renderParameter(
Parameter param, {
required String prefix,
required String suffix,
bool showMetadata = true,
}) {
final buffer = StringBuffer(prefix);
final buffer = StringBuffer();
final modelType = param.modelType;

if (showMetadata && param.hasAnnotations) {
Expand Down
34 changes: 18 additions & 16 deletions test/end2end/model_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -345,14 +345,15 @@ void main() async {
expect(
m1.linkedParamsLines,
equals(
'<ol class="parameter-list"><li><span class="parameter" id="m1-param-some"><span class="type-annotation">int</span> <span class="parameter-name">some</span>, </span></li>\n'
'<ol class="parameter-list"> <li><span class="parameter" id="m1-param-some"><span class="type-annotation">int</span> <span class="parameter-name">some</span>, </span></li>\n'
'<li><span class="parameter" id="m1-param-regular"><span class="type-annotation">dynamic</span> <span class="parameter-name">regular</span>, </span></li>\n'
'<li><span class="parameter" id="m1-param-parameters"><span>covariant</span> <span class="type-annotation">dynamic</span> <span class="parameter-name">parameters</span>, </span></li>\n'
'<li><span class="parameter" id="m1-param-p1">{<span>required</span> <span class="type-annotation">dynamic</span> <span class="parameter-name">p1</span>, </span></li>\n'
'<li><span class="parameter" id="m1-param-parameters"><span>covariant</span> <span class="type-annotation">dynamic</span> <span class="parameter-name">parameters</span>, {</span></li>\n'
'<li><span class="parameter" id="m1-param-p1"><span>required</span> <span class="type-annotation">dynamic</span> <span class="parameter-name">p1</span>, </span></li>\n'
'<li><span class="parameter" id="m1-param-p2"><span class="type-annotation">int</span> <span class="parameter-name">p2</span> = <span class="default-value">3</span>, </span></li>\n'
'<li><span class="parameter" id="m1-param-p3"><span>required</span> <span>covariant</span> <span class="type-annotation">dynamic</span> <span class="parameter-name">p3</span>, </span></li>\n'
'<li><span class="parameter" id="m1-param-p4"><span>required</span> <span>covariant</span> <span class="type-annotation">int</span> <span class="parameter-name">p4</span>}</span></li>\n'
'</ol>'));
'<li><span class="parameter" id="m1-param-p4"><span>required</span> <span>covariant</span> <span class="type-annotation">int</span> <span class="parameter-name">p4</span>, </span></li>\n'
'</ol>\n'
'}'));
});

test('verify no regression on ordinary optionals', () {
Expand All @@ -369,11 +370,12 @@ void main() async {
expect(
m2.linkedParamsLines,
equals(
'<ol class="parameter-list"><li><span class="parameter" id="m2-param-sometimes"><span class="type-annotation">int</span> <span class="parameter-name">sometimes</span>, </span></li>\n'
'<li><span class="parameter" id="m2-param-we"><span class="type-annotation">dynamic</span> <span class="parameter-name">we</span>, </span></li>\n'
'<li><span class="parameter" id="m2-param-have">[<span class="type-annotation">String</span> <span class="parameter-name">have</span>, </span></li>\n'
'<li><span class="parameter" id="m2-param-optionals"><span class="type-annotation">double</span> <span class="parameter-name">optionals</span>]</span></li>\n'
'</ol>'));
'<ol class="parameter-list"> <li><span class="parameter" id="m2-param-sometimes"><span class="type-annotation">int</span> <span class="parameter-name">sometimes</span>, </span></li>\n'
'<li><span class="parameter" id="m2-param-we"><span class="type-annotation">dynamic</span> <span class="parameter-name">we</span>, [</span></li>\n'
'<li><span class="parameter" id="m2-param-have"><span class="type-annotation">String</span> <span class="parameter-name">have</span>, </span></li>\n'
'<li><span class="parameter" id="m2-param-optionals"><span class="type-annotation">double</span> <span class="parameter-name">optionals</span>, </span></li>\n'
'</ol>\n'
']'));
});

test('anonymous callback parameters are correctly marked as nullable', () {
Expand All @@ -384,7 +386,7 @@ void main() async {
expect(onDone.isNamed, isTrue);

expect(m3.linkedParamsLines, contains('</ol>\n)?, '));
expect(m3.linkedParamsLines, contains('</ol>\n)?}</span>'));
expect(m3.linkedParamsLines, contains('</ol>\n}'));
});

test('Late final class member test', () {
Expand Down Expand Up @@ -3245,7 +3247,7 @@ void main() async {
topLevelFunction2.linkedParamsLines,
contains('<span class="parameter-name">p3</span> = '
'<span class="default-value">const &lt;String, int&gt;{}</span>'
']</span>'));
'</span>'));
});

test('has source code', () {
Expand Down Expand Up @@ -3288,11 +3290,11 @@ String? topLevelFunction(int param1, bool param2, Cool coolBeans,
.renderLinkedParams(doAComplicatedThing.parameters);
expect(
params,
'<span class="parameter" id="doAComplicatedThing-param-x"><span class="type-annotation">int</span> <span class="parameter-name">x</span>, </span>'
'<span class="parameter" id="doAComplicatedThing-param-doSomething">{<span class="type-annotation">void</span> <span class="parameter-name">doSomething</span>(<span class="parameter" id="doSomething-param-aThingParameter"><span class="type-annotation">int</span> <span class="parameter-name">aThingParameter</span>, </span>'
'<span class="parameter" id="doAComplicatedThing-param-x"><span class="type-annotation">int</span> <span class="parameter-name">x</span>, {</span>'
'<span class="parameter" id="doAComplicatedThing-param-doSomething"><span class="type-annotation">void</span> <span class="parameter-name">doSomething</span>(<span class="parameter" id="doSomething-param-aThingParameter"><span class="type-annotation">int</span> <span class="parameter-name">aThingParameter</span>, </span>'
'<span class="parameter" id="doSomething-param-anotherThing"><span class="type-annotation">String</span> <span class="parameter-name">anotherThing</span></span>)?, </span>'
'<span class="parameter" id="doAComplicatedThing-param-doSomethingElse"><span class="type-annotation">void</span> <span class="parameter-name">doSomethingElse</span>(<span class="parameter" id="doSomethingElse-param-aThingParameter"><span class="type-annotation">int</span> <span class="parameter-name">aThingParameter</span>, </span>'
'<span class="parameter" id="doSomethingElse-param-somethingElse"><span class="type-annotation">double</span> <span class="parameter-name">somethingElse</span></span>)?}</span>');
'<span class="parameter" id="doSomethingElse-param-somethingElse"><span class="type-annotation">double</span> <span class="parameter-name">somethingElse</span></span>)?</span>}');
});
});

Expand Down Expand Up @@ -4532,7 +4534,7 @@ String? topLevelFunction(int param1, bool param2, Cool coolBeans,
);
expect(
aComplexTypedef.linkedParamsLines,
'<ol class="parameter-list">'
'<ol class="parameter-list single-line"> '
'<li><span class="parameter" id="param-"><span class="type-annotation">A3</span>, </span></li>\n'
'<li><span class="parameter" id="param-"><span class="type-annotation">String</span></span></li>\n'
'</ol>',
Expand Down
Loading

0 comments on commit 6ef7589

Please sign in to comment.