X Tutup
Skip to content

Commit ad3b9cf

Browse files
committed
fix(dts generation): rewrite the d.ts file code generator to fix bugs and apply type remap correctly
Previously the type remap was not being applied to comments and free floating functions. The nunjucks template was becoming unreadable so rather than making a tweak there I rewrote it into imperative code that is much easier to follow. The output was diffed against the old output. The diff contained only the expected changes.
1 parent 34deda5 commit ad3b9cf

File tree

3 files changed

+189
-74
lines changed

3 files changed

+189
-74
lines changed
Lines changed: 186 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,192 @@
1-
module.exports = {
1+
'use strict';
22

3-
signature: function(remap) {
4-
return function(ast) {
5-
try {
6-
var text = [];
7-
if (ast.isStatic) text.push('static ');
8-
text.push(ast.name);
9-
if (ast.optional) text.push('?');
10-
if (ast.typeParameters) {
11-
text.push('<');
12-
text.push(ast.typeParameters.join(', '));
13-
text.push('>');
14-
}
15-
if (ast.parameters) {
16-
text.push('(');
17-
text.push(ast.parameters.join(', '));
18-
text.push(')');
19-
}
20-
if (ast.returnType) {
21-
text.push(': ', ast.returnType);
22-
} else if (ast.parameters) {
23-
text.push(': void');
24-
} else {
25-
text.push(': any');
26-
}
27-
var string = text.join('');
28-
for (var key in remap) {
29-
if (remap.hasOwnProperty(key)) {
30-
string = string.replace(new RegExp('\\b' + key + '\\b', 'gm'), remap[key]);
31-
}
3+
function DtsSerializer(remap) {
4+
this.remap = remap;
5+
}
6+
7+
DtsSerializer.prototype = {
8+
9+
constructor: DtsSerializer,
10+
11+
declaration: function(buffer, ast) {
12+
buffer.push(ast.name);
13+
if (ast.optional) buffer.push('?');
14+
if (ast.typeParameters) {
15+
buffer.push('<');
16+
buffer.push(ast.typeParameters.join(', '));
17+
buffer.push('>');
18+
}
19+
if (ast.parameters) {
20+
buffer.push('(');
21+
buffer.push(ast.parameters.join(', '));
22+
buffer.push(')');
23+
}
24+
if (ast.returnType) {
25+
buffer.push(': ', ast.returnType);
26+
} else if (ast.parameters) {
27+
buffer.push(': void');
28+
} else {
29+
buffer.push(': any');
30+
}
31+
buffer.push(';\n');
32+
},
33+
34+
comment: function(buffer, commentText) {
35+
if (!(commentText && commentText.match(/\S/))) return;
36+
37+
buffer.push('/**\n');
38+
commentText.replace(/\n*$/, '').split('\n').forEach(function(line) {
39+
buffer.push(' * ' + line + '\n');
40+
});
41+
buffer.push(' */\n');
42+
},
43+
44+
member: function(buffer, ast) {
45+
buffer.push('\n');
46+
this.comment(buffer, ast.content);
47+
48+
if (ast.isStatic) buffer.push('static ');
49+
this.declaration(buffer, ast);
50+
},
51+
52+
interfaceOrClass: function(buffer, ast, isInterface) {
53+
buffer.push(isInterface ? 'interface ' : 'class ');
54+
buffer.push(ast.name);
55+
buffer.push(ast.typeParams);
56+
buffer.push(ast.heritage);
57+
buffer.push(' {');
58+
buffer.indent();
59+
if (ast.newMember) this.member(buffer, ast.newMember);
60+
if (ast.callMember) this.member(buffer, ast.callMember);
61+
62+
ast.statics.forEach(function(staticMember) {
63+
this.member(buffer, staticMember);
64+
}.bind(this));
65+
66+
ast.members.forEach(function(member) {
67+
this.member(buffer, member);
68+
}.bind(this));
69+
70+
buffer.unindent();
71+
buffer.push('}');
72+
},
73+
74+
enum: function(buffer, ast) {
75+
buffer.push('enum ');
76+
buffer.push(ast.name);
77+
buffer.push(ast.typeParams);
78+
buffer.push(ast.heritage);
79+
buffer.push(' {');
80+
buffer.indent();
81+
82+
ast.members.forEach(function(member, index) {
83+
buffer.push('\n');
84+
this.comment(buffer, member.content);
85+
buffer.push(member.name);
86+
if (index !== (ast.members.length - 1)) {
87+
buffer.push(',\n');
88+
}
89+
}.bind(this));
90+
91+
buffer.unindent();
92+
buffer.push('}\n');
93+
},
94+
95+
function: function(buffer, ast) {
96+
buffer.push('function ');
97+
this.declaration(buffer, ast);
98+
},
99+
100+
var: function(buffer, ast) {
101+
buffer.push('var ');
102+
this.declaration(buffer, ast);
103+
},
104+
105+
const: function(buffer, ast) {
106+
buffer.push('const ');
107+
this.declaration(buffer, ast);
108+
},
109+
110+
serializeExport: function(ast) {
111+
var buffer = new Buffer();
112+
buffer.push('\n');
113+
114+
try {
115+
this.comment(buffer, ast.content);
116+
117+
switch (ast.docType) {
118+
case 'class': this.interfaceOrClass(buffer, ast, false); break;
119+
case 'interface': this.interfaceOrClass(buffer, ast, true); break;
120+
case 'function': this.function(buffer, ast); break;
121+
case 'enum': this.enum(buffer, ast); break;
122+
case 'var': this.var(buffer, ast); break;
123+
case 'const': this.const(buffer, ast); break;
124+
default: throw new Error("unknown docType: " + ast.docType);
125+
}
126+
127+
var string = buffer.toString();
128+
for (var key in this.remap) {
129+
if (this.remap.hasOwnProperty(key)) {
130+
string = string.replace(new RegExp('\\b' + key + '\\b', 'gm'), this.remap[key]);
32131
}
33-
return string;
34-
} catch (e) {
35-
console.log(e.toString(), e.stack);
36-
return 'ERROR: ' + e.toString();
37132
}
133+
134+
return string;
135+
} catch (e) {
136+
console.log(e.toString(), e.stack);
137+
return 'ERROR: ' + e.toString();
38138
}
39139
}
40140
};
141+
142+
143+
function Buffer() {
144+
this._globalBuffer = [];
145+
this._indentedBuffer = [];
146+
this._indentationLevel = 1;
147+
}
148+
149+
Buffer.prototype = {
150+
constructor: Buffer,
151+
152+
push: function() {
153+
this._indentedBuffer.push.apply(this._indentedBuffer, arguments);
154+
},
155+
156+
indent: function() {
157+
this._globalBuffer.push({indentationLevel: this._indentationLevel, content: this._indentedBuffer.join('')});
158+
this._indentationLevel++;
159+
this._indentedBuffer = [];
160+
},
161+
162+
unindent: function() {
163+
this._globalBuffer.push({indentationLevel: this._indentationLevel, content: this._indentedBuffer.join('')});
164+
this._indentationLevel--;
165+
this._indentedBuffer = [];
166+
},
167+
168+
toString: function() {
169+
if (this._indentationLevel !== 1) {
170+
throw new Exception("Forgot to unindent? Indentation level: " + this._indentationLevel);
171+
}
172+
173+
this.unindent();
174+
175+
var string = '';
176+
177+
this._globalBuffer.forEach(function(indentedChunk) {
178+
var indentation = (new Array(indentedChunk.indentationLevel * 2 + 1)).join(' ');
179+
indentedChunk.content.split('\n').forEach(function(line) {
180+
string += indentation + line + '\n';
181+
});
182+
183+
});
184+
185+
return string;
186+
}
187+
};
188+
189+
190+
module.exports = {
191+
DtsSerializer: DtsSerializer
192+
};

docs/typescript-definition-package/processors/createTypeDefinitionFile.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ module.exports = function createTypeDefinitionFile(log) {
4242
references: def.references
4343
};
4444
}),
45-
signature: codeGen.signature(def.remapTypes)
45+
dts: new codeGen.DtsSerializer(def.remapTypes)
4646
};
4747
});
4848

@@ -82,7 +82,7 @@ module.exports = function createTypeDefinitionFile(log) {
8282
docType: 'var',
8383
name: exportDoc.name,
8484
id: exportDoc.id,
85-
heritage: ': InjectableReference'
85+
returnType: 'InjectableReference'
8686
});
8787
}
8888
});

docs/typescript-definition-package/templates/type-definition.template.html

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,6 @@
88
{%- endmacro -%}
99

1010

11-
{%- macro memberInfo(signature, member) -%}
12-
{$ commentBlock(member, 5) $}
13-
{$ signature(member) $};
14-
{%- endmacro -%}
15-
16-
1711
// Type definitions for Angular v{$ versionInfo.currentVersion.full | replace(r/\+/, "_") $}
1812
// Project: http://angular.io/
1913
// Definitions by: angular team <https://github.com/angular/>
@@ -38,38 +32,7 @@
3832
declare module {$ module.namespace $} {
3933

4034
{%- for export in module.doc.exports -%}
41-
{%- if export.content -%}
42-
{$ commentBlock(export, 3) $}
43-
{%- endif %}
44-
{$ export.docType $} {$ export.name $}{$ export.typeParams $}{%- if export.heritage == ' extends Directive' %} extends DirectiveAnnotation{% else %}{$ export.heritage $}{% endif %}
45-
{%- if export.docType == 'class' or export.docType == 'interface' %} {
46-
{%- if export.newMember %}
47-
{$ memberInfo(doc.signature, export.newMember) $}
48-
{% endif %}
49-
{%- if export.callMember %}
50-
{$ memberInfo(doc.signature, export.callMember) $}
51-
{% endif -%}
52-
{%- for static in export.statics %}
53-
{$ memberInfo(doc.signature, static) $}
54-
{%- endfor -%}
55-
{%- for member in export.members %}
56-
{$ memberInfo(doc.signature, member) $}
57-
{%- endfor %}
58-
}
59-
60-
{%- elif export.docType == 'enum' %} {
61-
{%- for member in export.members %}
62-
{$ commentBlock(member, 5) $}
63-
{$ member.name $}{% if not loop.last %},
64-
{%- endif -%}
65-
{%- endfor %}
66-
}
67-
68-
{%- else -%}
69-
{% if export.parameters %}({% for param in export.parameters %}{$ param $}{% if not loop.last %}, {% endif %}{% endfor %}){%- endif %}
70-
{%- if export.returnType %} : {$ export.returnType $} {% endif -%}
71-
;
72-
{%- endif %}
35+
{$ doc.dts.serializeExport(export) $}
7336
{% endfor %}
7437
}
7538

0 commit comments

Comments
 (0)
X Tutup