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