diff --git a/src/diagnostics.rs b/src/diagnostics.rs index 0685acd2..44bc32fb 100644 --- a/src/diagnostics.rs +++ b/src/diagnostics.rs @@ -510,6 +510,18 @@ impl<'a, 'b> DiagnosticDocNodeVisitor<'a, 'b> { } fn visit_interface_def(&mut self, def: &crate::interface::InterfaceDef) { + // constructors + for constructor in &def.constructors { + self + .diagnostics + .check_missing_js_doc(&constructor.js_doc, &constructor.location); + self.diagnostics.check_missing_return_type( + constructor.return_type.as_ref(), + &constructor.js_doc, + &constructor.location, + ); + } + // properties for prop in &def.properties { self diff --git a/src/interface.rs b/src/interface.rs index f4ff35ac..7d0e63bf 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -7,6 +7,7 @@ use serde::Serialize; use crate::params::ts_fn_param_to_param_def; use crate::ts_type::CallSignatureDef; +use crate::ts_type::ConstructorDef; use crate::ts_type::IndexSignatureDef; use crate::ts_type::MethodDef; use crate::ts_type::PropertyDef; @@ -23,6 +24,8 @@ pub struct InterfaceDef { /// set when the interface is a default export pub def_name: Option, pub extends: Vec, + #[serde(default)] + pub constructors: Vec, pub methods: Vec, pub properties: Vec, pub call_signatures: Vec, @@ -78,6 +81,7 @@ pub fn get_doc_for_ts_interface_decl( ) -> (String, InterfaceDef) { let interface_name = interface_decl.id.sym.to_string(); + let mut constructors = vec![]; let mut methods = vec![]; let mut properties = vec![]; let mut call_signatures = vec![]; @@ -266,7 +270,7 @@ pub fn get_doc_for_ts_interface_decl( } } TsConstructSignatureDecl(ts_construct_sig) => { - if let Some(construct_js_doc) = + if let Some(js_doc) = js_doc_for_range(parsed_source, &ts_construct_sig.range()) { let mut params = vec![]; @@ -286,19 +290,15 @@ pub fn get_doc_for_ts_interface_decl( .as_ref() .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); - let construct_sig_def = MethodDef { - name: "new".to_string(), - kind: deno_ast::swc::ast::MethodKind::Method, - js_doc: construct_js_doc, + let construct_sig_def = ConstructorDef { + js_doc, location: get_location(parsed_source, ts_construct_sig.start()), - computed: false, - optional: false, params, return_type: maybe_return_type, type_params, }; - methods.push(construct_sig_def); + constructors.push(construct_sig_def); } } } @@ -318,6 +318,7 @@ pub fn get_doc_for_ts_interface_decl( let interface_def = InterfaceDef { def_name, extends, + constructors, methods, properties, call_signatures, diff --git a/src/printer.rs b/src/printer.rs index ed91626d..0c2bd047 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -463,6 +463,10 @@ impl<'a> DocPrinter<'a> { ) -> FmtResult { let interface_def = node.interface_def.as_ref().unwrap(); + for constructor in &interface_def.constructors { + writeln!(w, "{}{}", Indent(1), constructor)?; + self.format_jsdoc(w, &constructor.js_doc, 2)?; + } for property_def in &interface_def.properties { writeln!(w, "{}{}", Indent(1), property_def)?; self.format_jsdoc(w, &property_def.js_doc, 2)?; diff --git a/src/tests.rs b/src/tests.rs index 5c76c738..b4e726ae 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -358,6 +358,7 @@ export { Hello } from "./reexport.ts"; "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], @@ -937,6 +938,7 @@ async fn json_module() { "repr": "", "kind": "typeLiteral", "typeLiteral": { + "constructors": [], "methods": [], "properties": [{ "name": "a", @@ -1031,6 +1033,7 @@ async fn json_module() { "repr": "", "kind": "typeLiteral", "typeLiteral": { + "constructors": [], "methods": [], "properties": [{ "name": "a", diff --git a/src/ts_type.rs b/src/ts_type.rs index 07f1e044..a304b246 100644 --- a/src/ts_type.rs +++ b/src/ts_type.rs @@ -336,6 +336,7 @@ impl TsTypeDef { } fn ts_type_lit(parsed_source: &ParsedSource, other: &TsTypeLit) -> Self { + let mut constructors = vec![]; let mut methods = vec![]; let mut properties = vec![]; let mut call_signatures = vec![]; @@ -538,25 +539,22 @@ impl TsTypeDef { .as_ref() .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); - let construct_sig_def = MethodDef { - name: "new".to_string(), + let construct_sig_def = ConstructorDef { js_doc: prop_js_doc, - kind: MethodKind::Method, location: get_location(parsed_source, ts_construct_sig.start()), - computed: false, - optional: false, params, return_type: maybe_return_type, type_params, }; - methods.push(construct_sig_def); + constructors.push(construct_sig_def); } } } } let type_literal = TsTypeLiteralDef { + constructors, methods, properties, call_signatures, @@ -927,6 +925,28 @@ pub struct TsMappedTypeDef { pub ts_type: Option>, } +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct ConstructorDef { + #[serde(skip_serializing_if = "JsDoc::is_empty", default)] + pub js_doc: JsDoc, + pub params: Vec, + pub return_type: Option, + pub type_params: Vec, + pub location: Location, +} + +impl Display for ConstructorDef { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!( + f, + "{}({})", + colors::magenta("constructor"), + SliceDisplayer::new(&self.params, ", ", false), + ) + } +} + #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[serde(rename_all = "camelCase")] pub struct MethodDef { @@ -1081,6 +1101,8 @@ impl Display for IndexSignatureDef { #[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)] #[serde(rename_all = "camelCase")] pub struct TsTypeLiteralDef { + #[serde(default)] + pub constructors: Vec, pub methods: Vec, pub properties: Vec, pub call_signatures: Vec, diff --git a/tests/specs/Jsdoc.txt b/tests/specs/Jsdoc.txt index 9af7fd51..9116fb21 100644 --- a/tests/specs/Jsdoc.txt +++ b/tests/specs/Jsdoc.txt @@ -85,6 +85,7 @@ interface B }, "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/destructuring_assignment_object.txt b/tests/specs/destructuring_assignment_object.txt index 743e634a..e83a5cc0 100644 --- a/tests/specs/destructuring_assignment_object.txt +++ b/tests/specs/destructuring_assignment_object.txt @@ -51,6 +51,7 @@ private const rest "repr": "", "kind": "typeLiteral", "typeLiteral": { + "constructors": [], "methods": [], "properties": [ { diff --git a/tests/specs/destructuring_assignment_object_assignment.txt b/tests/specs/destructuring_assignment_object_assignment.txt index f9c9e211..b918390f 100644 --- a/tests/specs/destructuring_assignment_object_assignment.txt +++ b/tests/specs/destructuring_assignment_object_assignment.txt @@ -33,6 +33,7 @@ private const obj: { a: string; b: string; } "repr": "", "kind": "typeLiteral", "typeLiteral": { + "constructors": [], "methods": [], "properties": [ { diff --git a/tests/specs/export_class_object_extends.txt b/tests/specs/export_class_object_extends.txt index e52b8c8a..b4ccacf2 100644 --- a/tests/specs/export_class_object_extends.txt +++ b/tests/specs/export_class_object_extends.txt @@ -75,6 +75,7 @@ class Bar extends obj.Foo "repr": "", "kind": "typeLiteral", "typeLiteral": { + "constructors": [], "methods": [], "properties": [ { diff --git a/tests/specs/export_const_basic.txt b/tests/specs/export_const_basic.txt index 5f5f1147..a0715178 100644 --- a/tests/specs/export_const_basic.txt +++ b/tests/specs/export_const_basic.txt @@ -158,6 +158,7 @@ const tpl2: string "repr": "", "kind": "typeLiteral", "typeLiteral": { + "constructors": [], "methods": [ { "name": "get", diff --git a/tests/specs/export_default_interface.txt b/tests/specs/export_default_interface.txt index e36b2664..602d4054 100644 --- a/tests/specs/export_default_interface.txt +++ b/tests/specs/export_default_interface.txt @@ -34,6 +34,7 @@ interface default "interfaceDef": { "defName": "Reader", "extends": [], + "constructors": [], "methods": [ { "name": "read", diff --git a/tests/specs/export_fn2.txt b/tests/specs/export_fn2.txt index 6006b895..3b9734b0 100644 --- a/tests/specs/export_fn2.txt +++ b/tests/specs/export_fn2.txt @@ -170,6 +170,7 @@ private interface AssignOpts "declarationKind": "private", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [ { diff --git a/tests/specs/export_interface.txt b/tests/specs/export_interface.txt index aa885f1f..a405f73a 100644 --- a/tests/specs/export_interface.txt +++ b/tests/specs/export_interface.txt @@ -95,6 +95,7 @@ interface Reader extends Foo, Bar } } ], + "constructors": [], "methods": [ { "name": "read", @@ -199,6 +200,7 @@ interface Reader extends Foo, Bar "declarationKind": "private", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], @@ -218,6 +220,7 @@ interface Reader extends Foo, Bar "declarationKind": "private", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/export_interface2.txt b/tests/specs/export_interface2.txt index ea9094c2..f12ce4d5 100644 --- a/tests/specs/export_interface2.txt +++ b/tests/specs/export_interface2.txt @@ -40,6 +40,7 @@ interface TypedIface "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [ { "name": "something", diff --git a/tests/specs/export_interface_accessors.txt b/tests/specs/export_interface_accessors.txt index 5b758661..20cc722a 100644 --- a/tests/specs/export_interface_accessors.txt +++ b/tests/specs/export_interface_accessors.txt @@ -56,6 +56,7 @@ interface Thing "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [ { "name": "size", diff --git a/tests/specs/export_type_alias_literal.txt b/tests/specs/export_type_alias_literal.txt index df0e01fb..e1effe4e 100644 --- a/tests/specs/export_type_alias_literal.txt +++ b/tests/specs/export_type_alias_literal.txt @@ -18,7 +18,7 @@ error[missing-jsdoc]: exported symbol is missing JSDoc documentation # output.txt Defined in file:///mod.ts:1:1 -type A = { new(d: string): A; a(): void; b?(): void; c(): string; c(v: number); } +type A = { a(): void; b?(): void; c(): string; c(v: number); } # output.json @@ -38,16 +38,8 @@ type A = { new(d: string): A; a(): void; b?(): void; c(): string; c(v: number); "repr": "", "kind": "typeLiteral", "typeLiteral": { - "methods": [ + "constructors": [ { - "name": "new", - "kind": "method", - "location": { - "filename": "file:///mod.ts", - "line": 2, - "col": 2, - "byteIndex": 20 - }, "params": [ { "kind": "identifier", @@ -60,7 +52,6 @@ type A = { new(d: string): A; a(): void; b?(): void; c(): string; c(v: number); } } ], - "optional": false, "returnType": { "repr": "A", "kind": "typeRef", @@ -69,8 +60,16 @@ type A = { new(d: string): A; a(): void; b?(): void; c(): string; c(v: number); "typeName": "A" } }, - "typeParams": [] - }, + "typeParams": [], + "location": { + "filename": "file:///mod.ts", + "line": 2, + "col": 2, + "byteIndex": 20 + } + } + ], + "methods": [ { "name": "a", "kind": "method", diff --git a/tests/specs/exports_all_with_private.txt b/tests/specs/exports_all_with_private.txt index f27bc0e3..889c4a14 100644 --- a/tests/specs/exports_all_with_private.txt +++ b/tests/specs/exports_all_with_private.txt @@ -137,6 +137,7 @@ private namespace H "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], @@ -215,6 +216,7 @@ private namespace H "declarationKind": "private", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/generic_instantiated_with_tuple_type.txt b/tests/specs/generic_instantiated_with_tuple_type.txt index e649ffa5..685f91ca 100644 --- a/tests/specs/generic_instantiated_with_tuple_type.txt +++ b/tests/specs/generic_instantiated_with_tuple_type.txt @@ -42,6 +42,7 @@ interface Generic "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/import_equals.txt b/tests/specs/import_equals.txt index 8bfe78c6..b6e9a27f 100644 --- a/tests/specs/import_equals.txt +++ b/tests/specs/import_equals.txt @@ -37,6 +37,7 @@ interface Options "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/indented_with_tabs.txt b/tests/specs/indented_with_tabs.txt index b93ad1f2..68a9548a 100644 --- a/tests/specs/indented_with_tabs.txt +++ b/tests/specs/indented_with_tabs.txt @@ -75,6 +75,7 @@ namespace Tabs }, "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [ { diff --git a/tests/specs/infer_object_literal.txt b/tests/specs/infer_object_literal.txt index d2ab3fed..46f24c88 100644 --- a/tests/specs/infer_object_literal.txt +++ b/tests/specs/infer_object_literal.txt @@ -49,6 +49,7 @@ const a: { d(e: string): void; h(): string; h(value: string); [[t]](u: string): "repr": "", "kind": "typeLiteral", "typeLiteral": { + "constructors": [], "methods": [ { "name": "d", @@ -219,6 +220,7 @@ const a: { d(e: string): void; h(): string; h(value: string); [[t]](u: string): "repr": "", "kind": "typeLiteral", "typeLiteral": { + "constructors": [], "methods": [], "properties": [ { diff --git a/tests/specs/infer_object_literal_satifies.txt b/tests/specs/infer_object_literal_satifies.txt index a832b73c..dbae818d 100644 --- a/tests/specs/infer_object_literal_satifies.txt +++ b/tests/specs/infer_object_literal_satifies.txt @@ -109,6 +109,7 @@ type Colors = "red" | "green" | "blue" "repr": "", "kind": "typeLiteral", "typeLiteral": { + "constructors": [], "methods": [], "properties": [ { diff --git a/tests/specs/interface_construct.txt b/tests/specs/interface_construct.txt index 15e336d3..1415fe15 100644 --- a/tests/specs/interface_construct.txt +++ b/tests/specs/interface_construct.txt @@ -30,7 +30,7 @@ Defined in file:///mod.ts:1:1 interface I - new(name: string) + constructor(name: string) # output.json @@ -47,16 +47,8 @@ interface I "declarationKind": "export", "interfaceDef": { "extends": [], - "methods": [ + "constructors": [ { - "name": "new", - "kind": "method", - "location": { - "filename": "file:///mod.ts", - "line": 2, - "col": 2, - "byteIndex": 23 - }, "params": [ { "kind": "identifier", @@ -69,11 +61,17 @@ interface I } } ], - "optional": false, "returnType": null, - "typeParams": [] + "typeParams": [], + "location": { + "filename": "file:///mod.ts", + "line": 2, + "col": 2, + "byteIndex": 23 + } } ], + "methods": [], "properties": [], "callSignatures": [], "indexSignatures": [], diff --git a/tests/specs/interface_declaration.txt b/tests/specs/interface_declaration.txt index fc0f2772..6ac08170 100644 --- a/tests/specs/interface_declaration.txt +++ b/tests/specs/interface_declaration.txt @@ -30,6 +30,7 @@ interface Interface "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/interface_extends.txt b/tests/specs/interface_extends.txt index 92b79597..1edd3636 100644 --- a/tests/specs/interface_extends.txt +++ b/tests/specs/interface_extends.txt @@ -39,6 +39,7 @@ interface Interface extends Iterator } } ], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/interface_extends2.txt b/tests/specs/interface_extends2.txt index 89279729..e5228c53 100644 --- a/tests/specs/interface_extends2.txt +++ b/tests/specs/interface_extends2.txt @@ -47,6 +47,7 @@ interface Interface extends Iterator, Iterable } } ], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/interface_generic.txt b/tests/specs/interface_generic.txt index 5815d2ed..43ddba2e 100644 --- a/tests/specs/interface_generic.txt +++ b/tests/specs/interface_generic.txt @@ -30,6 +30,7 @@ interface Interface "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/interface_generic_extends.txt b/tests/specs/interface_generic_extends.txt index dab25fbe..1bfb9d6b 100644 --- a/tests/specs/interface_generic_extends.txt +++ b/tests/specs/interface_generic_extends.txt @@ -48,6 +48,7 @@ interface Interface extends Iterable } } ], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/interface_index_signature.txt b/tests/specs/interface_index_signature.txt index 604752a9..34f06b5d 100644 --- a/tests/specs/interface_index_signature.txt +++ b/tests/specs/interface_index_signature.txt @@ -40,6 +40,7 @@ interface Interface "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/interface_method.txt b/tests/specs/interface_method.txt index e5161244..8566857a 100644 --- a/tests/specs/interface_method.txt +++ b/tests/specs/interface_method.txt @@ -79,6 +79,7 @@ interface I "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [ { "name": "m", diff --git a/tests/specs/interface_number_literal_property.txt b/tests/specs/interface_number_literal_property.txt index 31a907c9..34aca9b5 100644 --- a/tests/specs/interface_number_literal_property.txt +++ b/tests/specs/interface_number_literal_property.txt @@ -49,6 +49,7 @@ interface I "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [ { diff --git a/tests/specs/interface_property.txt b/tests/specs/interface_property.txt index ffeb365d..fa1969ec 100644 --- a/tests/specs/interface_property.txt +++ b/tests/specs/interface_property.txt @@ -67,6 +67,7 @@ interface I "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [ { diff --git a/tests/specs/interface_readonly_index_signature.txt b/tests/specs/interface_readonly_index_signature.txt index 9d39c748..333d17dc 100644 --- a/tests/specs/interface_readonly_index_signature.txt +++ b/tests/specs/interface_readonly_index_signature.txt @@ -40,6 +40,7 @@ interface Interface "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/interface_string_literal_property.txt b/tests/specs/interface_string_literal_property.txt index b056bcba..9c4b9751 100644 --- a/tests/specs/interface_string_literal_property.txt +++ b/tests/specs/interface_string_literal_property.txt @@ -49,6 +49,7 @@ interface I "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [ { diff --git a/tests/specs/private_type_implementation_signature.txt b/tests/specs/private_type_implementation_signature.txt index 57ef0e51..dcce3eba 100644 --- a/tests/specs/private_type_implementation_signature.txt +++ b/tests/specs/private_type_implementation_signature.txt @@ -187,6 +187,7 @@ namespace SameName "declarationKind": "private", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], @@ -206,6 +207,7 @@ namespace SameName "declarationKind": "private", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/private_type_in_namespace.txt b/tests/specs/private_type_in_namespace.txt index a9c4f462..a153f6d9 100644 --- a/tests/specs/private_type_in_namespace.txt +++ b/tests/specs/private_type_in_namespace.txt @@ -76,6 +76,7 @@ private namespace Test "declarationKind": "export", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [ { diff --git a/tests/specs/private_type_private_member.txt b/tests/specs/private_type_private_member.txt index 3a3cf668..901a3f70 100644 --- a/tests/specs/private_type_private_member.txt +++ b/tests/specs/private_type_private_member.txt @@ -152,6 +152,7 @@ private interface YesDiagnostic "declarationKind": "private", "interfaceDef": { "extends": [], + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/type_literal_declaration.txt b/tests/specs/type_literal_declaration.txt index 850c12d8..c4d70a38 100644 --- a/tests/specs/type_literal_declaration.txt +++ b/tests/specs/type_literal_declaration.txt @@ -32,6 +32,7 @@ type T = { } "repr": "", "kind": "typeLiteral", "typeLiteral": { + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/type_literal_index_signature.txt b/tests/specs/type_literal_index_signature.txt index 09e5bdb7..7b81878d 100644 --- a/tests/specs/type_literal_index_signature.txt +++ b/tests/specs/type_literal_index_signature.txt @@ -32,6 +32,7 @@ type T = { [key: string]: number; } "repr": "", "kind": "typeLiteral", "typeLiteral": { + "constructors": [], "methods": [], "properties": [], "callSignatures": [], diff --git a/tests/specs/type_literal_readonly_index_signature.txt b/tests/specs/type_literal_readonly_index_signature.txt index 3f8dee09..dc198060 100644 --- a/tests/specs/type_literal_readonly_index_signature.txt +++ b/tests/specs/type_literal_readonly_index_signature.txt @@ -32,6 +32,7 @@ type T = { readonly [key: string]: number; } "repr": "", "kind": "typeLiteral", "typeLiteral": { + "constructors": [], "methods": [], "properties": [], "callSignatures": [],