v/vlib/v/gen/js/jsdoc.v

97 lines
2.0 KiB
V

module js
import v.ast
struct JsDoc {
mut:
gen &JsGen
}
fn new_jsdoc(gen &JsGen) &JsDoc {
return &JsDoc{
gen: gen
}
}
fn (mut d JsDoc) write(s string) {
if !d.gen.enable_doc {
return
}
d.gen.write(s)
}
fn (mut d JsDoc) writeln(s string) {
if !d.gen.enable_doc {
return
}
d.gen.writeln(s)
}
fn (mut d JsDoc) gen_typ(typ string) {
d.writeln('/** @type {$typ} */')
}
fn (mut d JsDoc) gen_const(typ string) {
d.writeln('/** @constant {$typ} */')
}
fn (mut d JsDoc) gen_enum() {
// Enum values can only be ints for now
typ := 'number'
d.writeln('/** @enum {$typ} */')
}
fn (mut d JsDoc) gen_fac_fn(fields []ast.StructField) {
d.writeln('/**')
d.writeln(' * @constructor')
d.write(' * @param {{')
for i, field in fields {
// Marked as optional: structs have default default values,
// so all struct members don't have to be initialized.
d.write('$field.name?: ${d.gen.typ(field.typ)}')
if i < fields.len - 1 {
d.write(', ')
}
}
d.writeln('}} init')
d.writeln('*/')
}
fn (mut d JsDoc) gen_fn(it ast.FnDecl) {
type_name := d.gen.typ(it.return_type)
d.writeln('/**')
d.writeln(' * @function')
if it.is_deprecated {
d.writeln(' * @deprecated')
}
for i, arg in it.params {
if (it.is_method || it.receiver.typ == 0) && i == 0 {
continue
}
arg_type_name := d.gen.typ(arg.typ)
is_varg := i == it.params.len - 1 && it.is_variadic
name := d.gen.js_name(arg.name)
if is_varg {
d.writeln(' * @param {...$arg_type_name} $name')
} else {
d.writeln(' * @param {$arg_type_name} $name')
}
}
d.writeln(' * @returns {$type_name}')
d.writeln('*/')
}
fn (mut d JsDoc) gen_interface(it ast.InterfaceDecl) {
name := d.gen.js_name(it.name)
d.writeln('/**')
d.writeln(' * @interface $name')
d.writeln(' * @typedef $name')
for method in it.methods {
// Skip receiver
typ := d.gen.fn_typ(method.params[1..], method.return_type)
method_name := d.gen.js_name(method.name)
d.writeln(' * @property {$typ} $method_name')
}
d.writeln(' */\n')
}