diff --git a/src/js_doc.rs b/src/js_doc.rs index 75fb367b..926e7020 100644 --- a/src/js_doc.rs +++ b/src/js_doc.rs @@ -19,7 +19,7 @@ lazy_static! { static ref JS_DOC_TAG_TYPED_RE: Regex = Regex::new(r"(?s)^\s*@(enum|extends|augments|this|type|default)\s+\{([^}]+)\}(?:\s+(.+))?").unwrap(); } -#[derive(Debug, Default, Clone, Deserialize, Serialize)] +#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq)] pub struct JsDoc { #[serde(skip_serializing_if = "Option::is_none", default)] pub doc: Option, diff --git a/src/parser.rs b/src/parser.rs index 55ed8b30..8810d21e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1291,6 +1291,7 @@ fn parse_json_module_type(value: &serde_json::Value) -> TsTypeDef { .iter() .map(|(key, value)| LiteralPropertyDef { name: key.to_string(), + js_doc: Default::default(), ts_type: Some(parse_json_module_type(value)), params: Vec::new(), readonly: false, diff --git a/src/tests.rs b/src/tests.rs index fffe3b8e..41c654a5 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -940,6 +940,7 @@ async fn json_module() { "methods": [], "properties": [{ "name": "a", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -954,6 +955,7 @@ async fn json_module() { "typeParams": [] }, { "name": "b", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -968,6 +970,7 @@ async fn json_module() { "typeParams": [] }, { "name": "c", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -979,6 +982,7 @@ async fn json_module() { "typeParams": [] }, { "name": "d", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -994,6 +998,7 @@ async fn json_module() { "typeParams": [] }, { "name": "e", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -1004,6 +1009,7 @@ async fn json_module() { "methods": [], "properties": [{ "name": "a", + "jsDoc": {}, "params": [], "computed": false, "optional": false, diff --git a/src/ts_type.rs b/src/ts_type.rs index 35e9c5c1..1c5c1955 100644 --- a/src/ts_type.rs +++ b/src/ts_type.rs @@ -13,10 +13,13 @@ use crate::params::ts_fn_param_to_param_def; use crate::ts_type_param::maybe_type_param_decl_to_type_param_defs; use crate::ts_type_param::TsTypeParamDef; use crate::util::swc::is_false; +use crate::util::swc::js_doc_for_range; use crate::ParamDef; +use crate::js_doc::JsDoc; use deno_ast::swc::ast::*; use deno_ast::ParsedSource; +use deno_ast::SourceRangedForSpanned; use serde::Deserialize; use serde::Serialize; use std::fmt::Display; @@ -337,171 +340,205 @@ impl TsTypeDef { match &type_element { TsMethodSignature(ts_method_sig) => { - let mut params = vec![]; - - for param in &ts_method_sig.params { - let param_def = ts_fn_param_to_param_def(parsed_source, param); - params.push(param_def); + if let Some(prop_js_doc) = + js_doc_for_range(parsed_source, &ts_method_sig.range()) + { + let params = ts_method_sig + .params + .iter() + .map(|param| ts_fn_param_to_param_def(parsed_source, param)) + .collect::>(); + + let maybe_return_type = ts_method_sig + .type_ann + .as_ref() + .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + + let type_params = maybe_type_param_decl_to_type_param_defs( + parsed_source, + ts_method_sig.type_params.as_deref(), + ); + let name = expr_to_name(&ts_method_sig.key); + let method_def = LiteralMethodDef { + name, + js_doc: prop_js_doc, + kind: MethodKind::Method, + params, + computed: ts_method_sig.computed, + optional: ts_method_sig.optional, + return_type: maybe_return_type, + type_params, + }; + methods.push(method_def); } - - let maybe_return_type = ts_method_sig - .type_ann - .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); - - let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, - ts_method_sig.type_params.as_deref(), - ); - let name = expr_to_name(&ts_method_sig.key); - let method_def = LiteralMethodDef { - name, - kind: MethodKind::Method, - params, - computed: ts_method_sig.computed, - optional: ts_method_sig.optional, - return_type: maybe_return_type, - type_params, - }; - methods.push(method_def); } TsGetterSignature(ts_getter_sig) => { - let maybe_return_type = ts_getter_sig - .type_ann - .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); - - let name = expr_to_name(&ts_getter_sig.key); - let method_def = LiteralMethodDef { - name, - kind: MethodKind::Getter, - params: vec![], - computed: ts_getter_sig.computed, - optional: ts_getter_sig.optional, - return_type: maybe_return_type, - type_params: vec![], - }; - methods.push(method_def); + if let Some(prop_js_doc) = + js_doc_for_range(parsed_source, &ts_getter_sig.range()) + { + let maybe_return_type = ts_getter_sig + .type_ann + .as_ref() + .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + + let name = expr_to_name(&ts_getter_sig.key); + let method_def = LiteralMethodDef { + name, + js_doc: prop_js_doc, + kind: MethodKind::Getter, + params: vec![], + computed: ts_getter_sig.computed, + optional: ts_getter_sig.optional, + return_type: maybe_return_type, + type_params: vec![], + }; + methods.push(method_def); + } } TsSetterSignature(ts_setter_sig) => { - let name = expr_to_name(&ts_setter_sig.key); - - let params = vec![ts_fn_param_to_param_def( - parsed_source, - &ts_setter_sig.param, - )]; - - let method_def = LiteralMethodDef { - name, - kind: MethodKind::Setter, - params, - computed: ts_setter_sig.computed, - optional: ts_setter_sig.optional, - return_type: None, - type_params: vec![], - }; - methods.push(method_def); + if let Some(prop_js_doc) = + js_doc_for_range(parsed_source, &ts_setter_sig.range()) + { + let name = expr_to_name(&ts_setter_sig.key); + + let params = vec![ts_fn_param_to_param_def( + parsed_source, + &ts_setter_sig.param, + )]; + + let method_def = LiteralMethodDef { + name, + js_doc: prop_js_doc, + kind: MethodKind::Setter, + params, + computed: ts_setter_sig.computed, + optional: ts_setter_sig.optional, + return_type: None, + type_params: vec![], + }; + methods.push(method_def); + } } TsPropertySignature(ts_prop_sig) => { - let name = expr_to_name(&ts_prop_sig.key); - - let params = ts_prop_sig - .params - .iter() - .map(|param| ts_fn_param_to_param_def(parsed_source, param)) - .collect(); - - let ts_type = ts_prop_sig - .type_ann - .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); - - let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, - ts_prop_sig.type_params.as_deref(), - ); - let prop_def = LiteralPropertyDef { - name, - params, - ts_type, - readonly: ts_prop_sig.readonly, - computed: ts_prop_sig.computed, - optional: ts_prop_sig.optional, - type_params, - }; - properties.push(prop_def); + if let Some(prop_js_doc) = + js_doc_for_range(parsed_source, &ts_prop_sig.range()) + { + let name = expr_to_name(&ts_prop_sig.key); + + let params = ts_prop_sig + .params + .iter() + .map(|param| ts_fn_param_to_param_def(parsed_source, param)) + .collect(); + + let ts_type = ts_prop_sig + .type_ann + .as_ref() + .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + + let type_params = maybe_type_param_decl_to_type_param_defs( + parsed_source, + ts_prop_sig.type_params.as_deref(), + ); + let prop_def = LiteralPropertyDef { + name, + js_doc: prop_js_doc, + params, + ts_type, + readonly: ts_prop_sig.readonly, + computed: ts_prop_sig.computed, + optional: ts_prop_sig.optional, + type_params, + }; + properties.push(prop_def); + } } TsCallSignatureDecl(ts_call_sig) => { - let mut params = vec![]; - for param in &ts_call_sig.params { - let param_def = ts_fn_param_to_param_def(parsed_source, param); - params.push(param_def); + if let Some(call_sig_js_doc) = + js_doc_for_range(parsed_source, &ts_call_sig.range()) + { + let params = ts_call_sig + .params + .iter() + .map(|param| ts_fn_param_to_param_def(parsed_source, param)) + .collect(); + + let ts_type = ts_call_sig + .type_ann + .as_ref() + .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + + let type_params = maybe_type_param_decl_to_type_param_defs( + parsed_source, + ts_call_sig.type_params.as_deref(), + ); + + let call_sig_def = LiteralCallSignatureDef { + js_doc: call_sig_js_doc, + params, + ts_type, + type_params, + }; + call_signatures.push(call_sig_def); } - - let ts_type = ts_call_sig - .type_ann - .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); - - let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, - ts_call_sig.type_params.as_deref(), - ); - - let call_sig_def = LiteralCallSignatureDef { - params, - ts_type, - type_params, - }; - call_signatures.push(call_sig_def); } TsIndexSignature(ts_index_sig) => { - let mut params = vec![]; - for param in &ts_index_sig.params { - let param_def = ts_fn_param_to_param_def(parsed_source, param); - params.push(param_def); + if let Some(js_doc) = + js_doc_for_range(parsed_source, &ts_index_sig.range()) + { + let params = ts_index_sig + .params + .iter() + .map(|param| ts_fn_param_to_param_def(parsed_source, param)) + .collect(); + + let ts_type = ts_index_sig + .type_ann + .as_ref() + .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + + let index_sig_def = LiteralIndexSignatureDef { + js_doc, + readonly: ts_index_sig.readonly, + params, + ts_type, + }; + index_signatures.push(index_sig_def); } - - let ts_type = ts_index_sig - .type_ann - .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); - - let index_sig_def = LiteralIndexSignatureDef { - readonly: ts_index_sig.readonly, - params, - ts_type, - }; - index_signatures.push(index_sig_def); } TsConstructSignatureDecl(ts_construct_sig) => { - let mut params = vec![]; - for param in &ts_construct_sig.params { - let param_def = ts_fn_param_to_param_def(parsed_source, param); - params.push(param_def); + if let Some(prop_js_doc) = + js_doc_for_range(parsed_source, &ts_construct_sig.range()) + { + let params = ts_construct_sig + .params + .iter() + .map(|param| ts_fn_param_to_param_def(parsed_source, param)) + .collect(); + + let type_params = maybe_type_param_decl_to_type_param_defs( + parsed_source, + ts_construct_sig.type_params.as_deref(), + ); + + let maybe_return_type = ts_construct_sig + .type_ann + .as_ref() + .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + + let construct_sig_def = LiteralMethodDef { + name: "new".to_string(), + js_doc: prop_js_doc, + kind: MethodKind::Method, + computed: false, + optional: false, + params, + return_type: maybe_return_type, + type_params, + }; + + methods.push(construct_sig_def); } - - let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, - ts_construct_sig.type_params.as_deref(), - ); - - let maybe_return_type = ts_construct_sig - .type_ann - .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); - - let construct_sig_def = LiteralMethodDef { - name: "new".to_string(), - kind: MethodKind::Method, - computed: false, - optional: false, - params, - return_type: maybe_return_type, - type_params, - }; - - methods.push(construct_sig_def); } } } @@ -593,12 +630,11 @@ impl TsTypeDef { let fn_def = match other { TsFnType(ts_fn_type) => { - let mut params = vec![]; - - for param in &ts_fn_type.params { - let param_def = ts_fn_param_to_param_def(parsed_source, param); - params.push(param_def); - } + let params = ts_fn_type + .params + .iter() + .map(|param| ts_fn_param_to_param_def(parsed_source, param)) + .collect(); let type_params = maybe_type_param_decl_to_type_param_defs( parsed_source, @@ -613,12 +649,11 @@ impl TsTypeDef { } } TsConstructorType(ctor_type) => { - let mut params = vec![]; - - for param in &ctor_type.params { - let param_def = ts_fn_param_to_param_def(parsed_source, param); - params.push(param_def); - } + let params = ctor_type + .params + .iter() + .map(|param| ts_fn_param_to_param_def(parsed_source, param)) + .collect(); let type_params = maybe_type_param_decl_to_type_param_defs( parsed_source, @@ -883,7 +918,9 @@ pub struct TsMappedTypeDef { #[serde(rename_all = "camelCase")] pub struct LiteralMethodDef { pub name: String, - pub kind: deno_ast::swc::ast::MethodKind, + #[serde(default)] + pub js_doc: JsDoc, + pub kind: MethodKind, pub params: Vec, #[serde(skip_serializing_if = "is_false", default)] pub computed: bool, @@ -912,6 +949,8 @@ impl Display for LiteralMethodDef { #[serde(rename_all = "camelCase")] pub struct LiteralPropertyDef { pub name: String, + #[serde(default)] + pub js_doc: JsDoc, pub params: Vec, #[serde(skip_serializing_if = "is_false", default)] pub readonly: bool, @@ -933,6 +972,8 @@ impl Display for LiteralPropertyDef { #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[serde(rename_all = "camelCase")] pub struct LiteralCallSignatureDef { + #[serde(default)] + pub js_doc: JsDoc, pub params: Vec, pub ts_type: Option, pub type_params: Vec, @@ -951,6 +992,8 @@ impl Display for LiteralCallSignatureDef { #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[serde(rename_all = "camelCase")] pub struct LiteralIndexSignatureDef { + #[serde(default)] + pub js_doc: JsDoc, pub readonly: bool, pub params: Vec, pub ts_type: Option, @@ -1686,6 +1729,7 @@ fn infer_ts_type_from_obj_inner( // from the previous symbol. properties.push(LiteralPropertyDef { name: shorthand.sym.to_string(), + js_doc: Default::default(), params: vec![], readonly: false, computed: false, @@ -1697,6 +1741,7 @@ fn infer_ts_type_from_obj_inner( Prop::KeyValue(kv) => { properties.push(LiteralPropertyDef { name: prop_name_to_string(parsed_source, &kv.key), + js_doc: Default::default(), params: vec![], readonly: false, computed: kv.key.is_computed(), @@ -1715,6 +1760,7 @@ fn infer_ts_type_from_obj_inner( .map(|type_ann| TsTypeDef::new(parsed_source, &type_ann.type_ann)); methods.push(LiteralMethodDef { name, + js_doc: Default::default(), kind: MethodKind::Getter, params: vec![], computed, @@ -1729,6 +1775,7 @@ fn infer_ts_type_from_obj_inner( let param = pat_to_param_def(parsed_source, setter.param.as_ref()); methods.push(LiteralMethodDef { name, + js_doc: Default::default(), kind: MethodKind::Setter, params: vec![param], computed, @@ -1756,6 +1803,7 @@ fn infer_ts_type_from_obj_inner( ); methods.push(LiteralMethodDef { name, + js_doc: Default::default(), kind: MethodKind::Method, params, computed, diff --git a/tests/specs/destructuring_assignment_object.txt b/tests/specs/destructuring_assignment_object.txt index 8cce0f4b..1480f0e3 100644 --- a/tests/specs/destructuring_assignment_object.txt +++ b/tests/specs/destructuring_assignment_object.txt @@ -55,6 +55,7 @@ private const rest "properties": [ { "name": "a", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -67,6 +68,7 @@ private const rest }, { "name": "b", + "jsDoc": {}, "params": [], "computed": false, "optional": false, diff --git a/tests/specs/destructuring_assignment_object_assignment.txt b/tests/specs/destructuring_assignment_object_assignment.txt index f6a376f6..8b523cd0 100644 --- a/tests/specs/destructuring_assignment_object_assignment.txt +++ b/tests/specs/destructuring_assignment_object_assignment.txt @@ -37,6 +37,7 @@ private const obj: { a: string; b: string; } "properties": [ { "name": "a", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -49,6 +50,7 @@ private const obj: { a: string; b: string; } }, { "name": "b", + "jsDoc": {}, "params": [], "computed": false, "optional": false, diff --git a/tests/specs/export_class_object_extends.txt b/tests/specs/export_class_object_extends.txt index ad065956..fe6e3f48 100644 --- a/tests/specs/export_class_object_extends.txt +++ b/tests/specs/export_class_object_extends.txt @@ -79,6 +79,7 @@ class Bar extends obj.Foo "properties": [ { "name": "Foo", + "jsDoc": {}, "params": [], "computed": false, "optional": false, diff --git a/tests/specs/export_const_basic.txt b/tests/specs/export_const_basic.txt index bfa0c4fc..caf3a7a0 100644 --- a/tests/specs/export_const_basic.txt +++ b/tests/specs/export_const_basic.txt @@ -161,6 +161,9 @@ const tpl2: string "methods": [ { "name": "get", + "jsDoc": { + "doc": "get doc" + }, "kind": "method", "params": [ { @@ -195,6 +198,9 @@ const tpl2: string }, { "name": "set", + "jsDoc": { + "doc": "set doc" + }, "kind": "method", "params": [ { diff --git a/tests/specs/export_type_alias_literal.txt b/tests/specs/export_type_alias_literal.txt index 7bdbb37a..ab9650d7 100644 --- a/tests/specs/export_type_alias_literal.txt +++ b/tests/specs/export_type_alias_literal.txt @@ -41,6 +41,7 @@ type A = { new(d: string): A; a(): void; b?(): void; c(): string; c(v: number); "methods": [ { "name": "new", + "jsDoc": {}, "kind": "method", "params": [ { @@ -67,6 +68,7 @@ type A = { new(d: string): A; a(): void; b?(): void; c(): string; c(v: number); }, { "name": "a", + "jsDoc": {}, "kind": "method", "params": [], "optional": false, @@ -79,6 +81,7 @@ type A = { new(d: string): A; a(): void; b?(): void; c(): string; c(v: number); }, { "name": "b", + "jsDoc": {}, "kind": "method", "params": [], "optional": true, @@ -91,6 +94,7 @@ type A = { new(d: string): A; a(): void; b?(): void; c(): string; c(v: number); }, { "name": "c", + "jsDoc": {}, "kind": "getter", "params": [], "optional": false, @@ -103,6 +107,7 @@ type A = { new(d: string): A; a(): void; b?(): void; c(): string; c(v: number); }, { "name": "c", + "jsDoc": {}, "kind": "setter", "params": [ { diff --git a/tests/specs/infer_object_literal.txt b/tests/specs/infer_object_literal.txt index 96053193..bf767ff4 100644 --- a/tests/specs/infer_object_literal.txt +++ b/tests/specs/infer_object_literal.txt @@ -52,6 +52,7 @@ const a: { d(e: string): void; h(): string; h(value: string); [[t]](u: string): "methods": [ { "name": "d", + "jsDoc": {}, "kind": "method", "params": [ { @@ -75,6 +76,7 @@ const a: { d(e: string): void; h(): string; h(value: string); [[t]](u: string): }, { "name": "h", + "jsDoc": {}, "kind": "getter", "params": [], "optional": false, @@ -87,6 +89,7 @@ const a: { d(e: string): void; h(): string; h(value: string); [[t]](u: string): }, { "name": "h", + "jsDoc": {}, "kind": "setter", "params": [ { @@ -106,6 +109,7 @@ const a: { d(e: string): void; h(): string; h(value: string); [[t]](u: string): }, { "name": "[t]", + "jsDoc": {}, "kind": "method", "params": [ { @@ -132,6 +136,7 @@ const a: { d(e: string): void; h(): string; h(value: string); [[t]](u: string): "properties": [ { "name": "a", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -144,6 +149,7 @@ const a: { d(e: string): void; h(): string; h(value: string); [[t]](u: string): }, { "name": "b", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -170,6 +176,7 @@ const a: { d(e: string): void; h(): string; h(value: string); [[t]](u: string): }, { "name": "c", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -181,6 +188,7 @@ const a: { d(e: string): void; h(): string; h(value: string); [[t]](u: string): "properties": [ { "name": "d", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -200,6 +208,7 @@ const a: { d(e: string): void; h(): string; h(value: string); [[t]](u: string): }, { "name": "f", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -232,6 +241,7 @@ const a: { d(e: string): void; h(): string; h(value: string); [[t]](u: string): }, { "name": "[s]", + "jsDoc": {}, "params": [], "computed": true, "optional": false, diff --git a/tests/specs/infer_object_literal_satifies.txt b/tests/specs/infer_object_literal_satifies.txt index 0b5e9bac..c31f35f1 100644 --- a/tests/specs/infer_object_literal_satifies.txt +++ b/tests/specs/infer_object_literal_satifies.txt @@ -113,6 +113,7 @@ type Colors = "red" | "green" | "blue" "properties": [ { "name": "red", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -125,6 +126,7 @@ type Colors = "red" | "green" | "blue" }, { "name": "green", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -137,6 +139,7 @@ type Colors = "red" | "green" | "blue" }, { "name": "blue", + "jsDoc": {}, "params": [], "computed": false, "optional": false, @@ -149,6 +152,7 @@ type Colors = "red" | "green" | "blue" }, { "name": "platypus", + "jsDoc": {}, "params": [], "computed": false, "optional": false, diff --git a/tests/specs/type_literal_index_signature.txt b/tests/specs/type_literal_index_signature.txt index a41e8763..eacf41a3 100644 --- a/tests/specs/type_literal_index_signature.txt +++ b/tests/specs/type_literal_index_signature.txt @@ -37,6 +37,7 @@ type T = { [key: string]: number; } "callSignatures": [], "indexSignatures": [ { + "jsDoc": {}, "readonly": false, "params": [ { diff --git a/tests/specs/type_literal_readonly_index_signature.txt b/tests/specs/type_literal_readonly_index_signature.txt index 0f8550cd..579f2a5d 100644 --- a/tests/specs/type_literal_readonly_index_signature.txt +++ b/tests/specs/type_literal_readonly_index_signature.txt @@ -37,6 +37,7 @@ type T = { readonly [key: string]: number; } "callSignatures": [], "indexSignatures": [ { + "jsDoc": {}, "readonly": true, "params": [ {