Skip to content

Commit 8c36926

Browse files
authored
Merge pull request #335 from ember-learn/fancier-function-signatures
Support fancier function signatures
2 parents bdb9ebc + 3e02d3d commit 8c36926

File tree

5 files changed

+144
-40
lines changed

5 files changed

+144
-40
lines changed

addon/components/api/x-section/template.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div data-test-item>
1+
<div data-test-item class="docs-pb-8">
22
<h3
33
id={{item.name}}
44
data-text="{{item.name}}"

addon/helpers/type-signature.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,27 @@ function escape(text) {
66
return text.replace(/</g, '&lt;').replace(/>/g, '&gt;');
77
}
88

9-
function functionSignature({ name, params, returns }) {
10-
let paramSignature = params.filter(p => !p.name.includes('.')).map(({ name, type }) => {
11-
return [`<strong>${name}</strong>`, `<em>${type}</em>`].join(': ');
12-
}).join(', ')
9+
function functionSignature(fn) {
10+
// Functions may have { params, typeParams, returns } directly on them, or they
11+
// may have a `signatures` array of hashes each with those properties.
12+
let signatures = (fn.signatures || [fn]).map(({ params, typeParams, returns }) => {
13+
let paramSignature = params.filter(p => !p.name.includes('.')).map(({ name, type, isRest, isOptional }) => {
14+
let prefix = isRest ? '...' : '';
15+
let suffix = isOptional ? '?' : '';
16+
return `${prefix}<strong>${name}</strong>${suffix}: <em>${type}</em>`;
17+
}).join(', ');
1318

14-
let returnType = returns ? returns.type : 'any';
19+
let typeParamSignature = '';
20+
if (typeParams && typeParams.length) {
21+
typeParamSignature = `&lt;${typeParams.map(p => `<em>${p}</em>`).join(', ')}&gt;`;
22+
}
1523

16-
return `<strong>${name}</strong>(${paramSignature}): <em>${returnType}</em>`;
24+
let returnType = returns ? returns.type : 'any';
25+
26+
return `<strong>${fn.name}</strong>${typeParamSignature}(${paramSignature}): <em>${returnType}</em>`;
27+
});
28+
29+
return signatures.join('<br>');
1730
}
1831

1932
function accessorSignature({ name, type, hasGetter, hasSetter }) {

addon/utils/compile-markdown.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@ import json from 'highlight.js/lib/languages/json';
1111
import xml from 'highlight.js/lib/languages/xml';
1212
import diff from 'highlight.js/lib/languages/diff';
1313
import shell from 'highlight.js/lib/languages/shell';
14+
import typescript from 'highlight.js/lib/languages/typescript';
1415

1516
hljs.registerLanguage('javascript', javascript);
17+
hljs.registerLanguage('js', javascript);
1618
hljs.registerLanguage('css', css);
1719
hljs.registerLanguage('handlebars', handlebars);
1820
hljs.registerLanguage('htmlbars', htmlbars);
21+
hljs.registerLanguage('hbs', htmlbars);
1922
hljs.registerLanguage('json', json);
2023
hljs.registerLanguage('xml', xml);
2124
hljs.registerLanguage('diff', diff);
2225
hljs.registerLanguage('shell', shell);
26+
hljs.registerLanguage('sh', shell);
27+
hljs.registerLanguage('typescript', typescript);
28+
hljs.registerLanguage('ts', typescript);
2329

2430
function highlightCode(code, lang) {
2531
return hljs.getLanguage(lang) ? hljs.highlight(lang, code).value : code

lib/utils/compile-doc-descriptions.js

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import { module, test } from 'qunit';
2+
import { setupRenderingTest } from 'ember-qunit';
3+
import { render } from '@ember/test-helpers';
4+
import hbs from 'htmlbars-inline-precompile';
5+
6+
module('Integration | Helpers | type-signature', function(hooks) {
7+
setupRenderingTest(hooks);
8+
9+
test('renders a simple getter signature', async function(assert) {
10+
this.set('item', {
11+
name: 'foo',
12+
hasGetter: true,
13+
type: 'string'
14+
});
15+
16+
await render(hbs`{{type-signature item}}`);
17+
18+
assert.equal(this.element.innerText, 'get foo: string');
19+
});
20+
21+
test('renders a simple setter signature', async function(assert) {
22+
this.set('item', {
23+
name: 'foo',
24+
hasSetter: true,
25+
type: 'string'
26+
});
27+
28+
await render(hbs`{{type-signature item}}`);
29+
30+
assert.equal(this.element.innerText, 'set foo: string');
31+
});
32+
33+
test('renders a simple getter signature', async function(assert) {
34+
this.set('item', {
35+
name: 'foo',
36+
hasGetter: true,
37+
hasSetter: true,
38+
type: 'string'
39+
});
40+
41+
await render(hbs`{{type-signature item}}`);
42+
43+
assert.equal(this.element.innerText, 'get/set foo: string');
44+
});
45+
46+
test('renders a simple variable', async function(assert) {
47+
this.set('item', { name: 'foo', type: 'string' });
48+
49+
await render(hbs`{{type-signature item}}`);
50+
51+
assert.equal(this.element.innerText, 'foo: string');
52+
});
53+
54+
test('renders a simple function signature', async function(assert) {
55+
this.set('item', { name: 'foo', params: [], returns: { type: 'string' } });
56+
57+
await render(hbs`{{type-signature item}}`);
58+
59+
assert.equal(this.element.innerText, 'foo(): string');
60+
});
61+
62+
test('renders static and access modifiers', async function(assert) {
63+
this.set('item', { name: 'foo', type: 'string', isStatic: true, access: 'private' });
64+
65+
await render(hbs`{{type-signature item}}`);
66+
67+
assert.equal(this.element.innerText, 'private static foo: string');
68+
});
69+
70+
test('renders functions with optional and rest params', async function(assert) {
71+
this.set('item', {
72+
name: 'foo',
73+
params: [
74+
{ name: 'a', type: 'number' },
75+
{ name: 'b', type: 'string', isOptional: true },
76+
{ name: 'c', type: 'any[]', isRest: true }
77+
]
78+
});
79+
80+
await render(hbs`{{type-signature item}}`);
81+
82+
assert.equal(this.element.innerText, 'foo(a: number, b?: string, ...c: any[]): any');
83+
});
84+
85+
test('renders functions with type params', async function(assert) {
86+
this.set('item', {
87+
name: 'foo',
88+
typeParams: ['T, U extends PromiseLike&lt;T&gt;'],
89+
params: [{ name: 'value', type: 'U' }],
90+
returns: { type: 'T' },
91+
});
92+
93+
await render(hbs`{{type-signature item}}`);
94+
95+
assert.equal(this.element.innerText, 'foo<T, U extends PromiseLike<T>>(value: U): T');
96+
});
97+
98+
test('renders functions with multiple signatures', async function(assert) {
99+
this.set('item', {
100+
name: 'foo',
101+
signatures: [
102+
{
103+
params: [],
104+
returns: { type: 'Promise&lt;void&gt;' }
105+
},
106+
{
107+
typeParams: ['T'],
108+
params: [{ name: 'value', type: 'T' }],
109+
returns: { type: 'Promise&lt;T&gt;' }
110+
}
111+
]
112+
});
113+
114+
await render(hbs`{{type-signature item}}`);
115+
116+
assert.equal(this.element.innerText, 'foo(): Promise<void>\nfoo<T>(value: T): Promise<T>');
117+
});
118+
});

0 commit comments

Comments
 (0)