v2 / vlib / v / gen / js / jsdoc.v
96 lines · 85 sloc · 2.01 KB · f31ba78de813ea04f4da18dc0542430a46277037
Raw
1module js
2
3import v.ast
4
5struct JsDoc {
6mut:
7 gen &JsGen = unsafe { nil }
8}
9
10fn new_jsdoc(gen &JsGen) &JsDoc {
11 return &JsDoc{
12 gen: gen
13 }
14}
15
16fn (mut d JsDoc) write(s string) {
17 if !d.gen.enable_doc {
18 return
19 }
20 d.gen.write(s)
21}
22
23fn (mut d JsDoc) writeln(s string) {
24 if !d.gen.enable_doc {
25 return
26 }
27 d.gen.writeln(s)
28}
29
30fn (mut d JsDoc) gen_typ(typ string) {
31 d.writeln('/** @type {${typ}} */')
32}
33
34fn (mut d JsDoc) gen_const(typ string) {
35 d.writeln('/** @constant {${typ}} */')
36}
37
38fn (mut d JsDoc) gen_enum() {
39 // Enum values can only be ints for now
40 typ := 'number'
41 d.writeln('/** @enum {${typ}} */')
42}
43
44fn (mut d JsDoc) gen_fac_fn(fields []ast.StructField) {
45 d.writeln('/**')
46 d.writeln(' * @constructor')
47 d.write(' * @param {{')
48 for i, field in fields {
49 // Marked as optional: structs have default default values,
50 // so all struct members don't have to be initialized.
51 d.write('${field.name}?: ${d.gen.styp(field.typ)}')
52 if i < fields.len - 1 {
53 d.write(', ')
54 }
55 }
56 d.writeln('}} init')
57 d.writeln('*/')
58}
59
60fn (mut d JsDoc) gen_fn(it ast.FnDecl) {
61 type_name := d.gen.styp(it.return_type)
62 d.writeln('/**')
63 d.writeln(' * @function')
64 if it.is_deprecated {
65 d.writeln(' * @deprecated')
66 }
67 for i, arg in it.params {
68 if (it.is_method || it.receiver.typ == 0) && i == 0 {
69 continue
70 }
71 arg_type_name := d.gen.styp(arg.typ)
72 is_varg := i == it.params.len - 1 && it.is_variadic
73 name := d.gen.js_name(arg.name)
74 if is_varg {
75 d.writeln(' * @param {...${arg_type_name}} ${name}')
76 } else {
77 d.writeln(' * @param {${arg_type_name}} ${name}')
78 }
79 }
80 d.writeln(' * @returns {${type_name}}')
81 d.writeln('*/')
82}
83
84fn (mut d JsDoc) gen_interface(it ast.InterfaceDecl) {
85 name := d.gen.js_name(it.name)
86 d.writeln('/**')
87 d.writeln(' * @interface ${name}')
88 d.writeln(' * @typedef ${name}')
89 for method in it.methods {
90 // Skip receiver
91 typ := d.gen.fn_typ(method.params[1..], method.return_type)
92 method_name := d.gen.js_name(method.name)
93 d.writeln(' * @property {${typ}} ${method_name}')
94 }
95 d.writeln(' */\n')
96}
97