mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
docs(docs-infra): Extract class constructors (#60302)
fixes #59180 PR Close #60302
This commit is contained in:
parent
647550918f
commit
db5963797d
4 changed files with 658 additions and 15 deletions
|
|
@ -754,6 +754,525 @@
|
|||
"startLine": 112,
|
||||
"endLine": 115
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HttpRequest",
|
||||
"isAbstract": false,
|
||||
"entryType": "undecorated_class",
|
||||
"members": [
|
||||
{
|
||||
"name": "constructor",
|
||||
"signatures": [
|
||||
{
|
||||
"name": "constructor",
|
||||
"params": [
|
||||
{
|
||||
"name": "method",
|
||||
"description": "",
|
||||
"type": "\"GET\" | \"HEAD\"",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "init",
|
||||
"description": "",
|
||||
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | undefined",
|
||||
"isOptional": true,
|
||||
"isRestParam": false
|
||||
}
|
||||
],
|
||||
"returnType": "foobar",
|
||||
"description": "",
|
||||
"entryType": "function",
|
||||
"jsdocTags": [],
|
||||
"rawComment": "",
|
||||
"generics": [],
|
||||
"isNewType": false
|
||||
},
|
||||
{
|
||||
"name": "constructor",
|
||||
"params": [
|
||||
{
|
||||
"name": "method",
|
||||
"description": "",
|
||||
"type": "\"DELETE\" | \"JSONP\" | \"OPTIONS\"",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "init",
|
||||
"description": "",
|
||||
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; } | undefined",
|
||||
"isOptional": true,
|
||||
"isRestParam": false
|
||||
}
|
||||
],
|
||||
"returnType": "foobar",
|
||||
"description": "",
|
||||
"entryType": "function",
|
||||
"jsdocTags": [],
|
||||
"rawComment": "",
|
||||
"generics": [],
|
||||
"isNewType": false
|
||||
},
|
||||
{
|
||||
"name": "constructor",
|
||||
"params": [
|
||||
{
|
||||
"name": "method",
|
||||
"description": "",
|
||||
"type": "\"POST\"",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"description": "",
|
||||
"type": "T | null",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "init",
|
||||
"description": "",
|
||||
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | undefined",
|
||||
"isOptional": true,
|
||||
"isRestParam": false
|
||||
}
|
||||
],
|
||||
"returnType": "foobar",
|
||||
"description": "",
|
||||
"entryType": "function",
|
||||
"jsdocTags": [],
|
||||
"rawComment": "",
|
||||
"generics": [],
|
||||
"isNewType": false
|
||||
},
|
||||
{
|
||||
"name": "constructor",
|
||||
"params": [
|
||||
{
|
||||
"name": "method",
|
||||
"description": "",
|
||||
"type": "\"PUT\" | \"PATCH\"",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"description": "",
|
||||
"type": "T | null",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "init",
|
||||
"description": "",
|
||||
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; } | undefined",
|
||||
"isOptional": true,
|
||||
"isRestParam": false
|
||||
}
|
||||
],
|
||||
"returnType": "foobar",
|
||||
"description": "",
|
||||
"entryType": "function",
|
||||
"jsdocTags": [],
|
||||
"rawComment": "",
|
||||
"generics": [],
|
||||
"isNewType": false
|
||||
},
|
||||
{
|
||||
"name": "constructor",
|
||||
"params": [
|
||||
{
|
||||
"name": "method",
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"description": "",
|
||||
"type": "T | null",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "init",
|
||||
"description": "",
|
||||
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | undefined",
|
||||
"isOptional": true,
|
||||
"isRestParam": false
|
||||
}
|
||||
],
|
||||
"returnType": "foobar",
|
||||
"description": "",
|
||||
"entryType": "function",
|
||||
"jsdocTags": [],
|
||||
"rawComment": "",
|
||||
"generics": [],
|
||||
"isNewType": false
|
||||
},
|
||||
{
|
||||
"name": "constructor",
|
||||
"params": [
|
||||
{
|
||||
"name": "method",
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "third",
|
||||
"description": "",
|
||||
"type": "T | { headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | null | undefined",
|
||||
"isOptional": true,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "fourth",
|
||||
"description": "",
|
||||
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | undefined",
|
||||
"isOptional": true,
|
||||
"isRestParam": false
|
||||
}
|
||||
],
|
||||
"returnType": "foobar",
|
||||
"description": "",
|
||||
"entryType": "function",
|
||||
"jsdocTags": [],
|
||||
"rawComment": "",
|
||||
"generics": [],
|
||||
"isNewType": false
|
||||
}
|
||||
],
|
||||
"implementation": {
|
||||
"params": [
|
||||
{
|
||||
"name": "method",
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "third",
|
||||
"description": "",
|
||||
"type": "T | { headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | null | undefined",
|
||||
"isOptional": true,
|
||||
"isRestParam": false
|
||||
},
|
||||
{
|
||||
"name": "fourth",
|
||||
"description": "",
|
||||
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; } | undefined",
|
||||
"isOptional": true,
|
||||
"isRestParam": false
|
||||
}
|
||||
],
|
||||
"isNewType": false,
|
||||
"returnType": "HttpRequest<T>",
|
||||
"generics": [],
|
||||
"name": "constructor",
|
||||
"description": "",
|
||||
"entryType": "function",
|
||||
"jsdocTags": [],
|
||||
"rawComment": ""
|
||||
},
|
||||
"entryType": "function",
|
||||
"description": "",
|
||||
"jsdocTags": [],
|
||||
"rawComment": "",
|
||||
"memberType": "method",
|
||||
"memberTags": []
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"type": "T | null",
|
||||
"memberType": "property",
|
||||
"memberTags": ["readonly"],
|
||||
"description": "The request body, or `null` if one isn't set.\n\nBodies are not enforced to be immutable, as they can include a reference to any\nuser-defined data type. However, interceptors should take care to preserve\nidempotence by treating them as such.",
|
||||
"jsdocTags": []
|
||||
},
|
||||
{
|
||||
"name": "headers",
|
||||
"type": "HttpHeaders",
|
||||
"memberType": "property",
|
||||
"memberTags": ["readonly"],
|
||||
"description": "Outgoing headers for this request.",
|
||||
"jsdocTags": []
|
||||
},
|
||||
{
|
||||
"name": "context",
|
||||
"type": "HttpContext",
|
||||
"memberType": "property",
|
||||
"memberTags": ["readonly"],
|
||||
"description": "Shared and mutable context that can be used by interceptors",
|
||||
"jsdocTags": []
|
||||
},
|
||||
{
|
||||
"name": "reportProgress",
|
||||
"type": "boolean",
|
||||
"memberType": "property",
|
||||
"memberTags": ["readonly"],
|
||||
"description": "Whether this request should be made in a way that exposes progress events.\n\nProgress events are expensive (change detection runs on each event) and so\nthey should only be requested if the consumer intends to monitor them.\n\nNote: The `FetchBackend` doesn't support progress report on uploads.",
|
||||
"jsdocTags": []
|
||||
},
|
||||
{
|
||||
"name": "withCredentials",
|
||||
"type": "boolean",
|
||||
"memberType": "property",
|
||||
"memberTags": ["readonly"],
|
||||
"description": "Whether this request should be sent with outgoing credentials (cookies).",
|
||||
"jsdocTags": []
|
||||
},
|
||||
{
|
||||
"name": "responseType",
|
||||
"type": "\"arraybuffer\" | \"blob\" | \"text\" | \"json\"",
|
||||
"memberType": "property",
|
||||
"memberTags": ["readonly"],
|
||||
"description": "The expected response type of the server.\n\nThis is used to parse the response appropriately before returning it to\nthe requestee.",
|
||||
"jsdocTags": []
|
||||
},
|
||||
{
|
||||
"name": "method",
|
||||
"type": "string",
|
||||
"memberType": "property",
|
||||
"memberTags": ["readonly"],
|
||||
"description": "The outgoing HTTP request method.",
|
||||
"jsdocTags": []
|
||||
},
|
||||
{
|
||||
"name": "params",
|
||||
"type": "HttpParams",
|
||||
"memberType": "property",
|
||||
"memberTags": ["readonly"],
|
||||
"description": "Outgoing URL parameters.\n\nTo pass a string representation of HTTP parameters in the URL-query-string format,\nthe `HttpParamsOptions`' `fromString` may be used. For example:\n\n```ts\nnew HttpParams({fromString: 'angular=awesome'})\n```",
|
||||
"jsdocTags": []
|
||||
},
|
||||
{
|
||||
"name": "urlWithParams",
|
||||
"type": "string",
|
||||
"memberType": "property",
|
||||
"memberTags": ["readonly"],
|
||||
"description": "The outgoing URL with all URL parameters set.",
|
||||
"jsdocTags": []
|
||||
},
|
||||
{
|
||||
"name": "transferCache",
|
||||
"type": "boolean | { includeHeaders?: string[] | undefined; } | undefined",
|
||||
"memberType": "property",
|
||||
"memberTags": ["readonly", "optional"],
|
||||
"description": "The HttpTransferCache option for the request",
|
||||
"jsdocTags": []
|
||||
},
|
||||
{
|
||||
"name": "serializeBody",
|
||||
"signatures": [
|
||||
{
|
||||
"name": "serializeBody",
|
||||
"entryType": "function",
|
||||
"description": "Transform the free-form body into a serialized format suitable for\ntransmission to the server.",
|
||||
"generics": [],
|
||||
"isNewType": false,
|
||||
"jsdocTags": [],
|
||||
"params": [],
|
||||
"rawComment": "/**\n * Transform the free-form body into a serialized format suitable for\n * transmission to the server.\n */",
|
||||
"returnType": "string | ArrayBuffer | Blob | FormData | URLSearchParams | null"
|
||||
}
|
||||
],
|
||||
"implementation": {
|
||||
"params": [],
|
||||
"isNewType": false,
|
||||
"returnType": "string | ArrayBuffer | Blob | FormData | URLSearchParams | null",
|
||||
"generics": [],
|
||||
"name": "serializeBody",
|
||||
"description": "Transform the free-form body into a serialized format suitable for\ntransmission to the server.",
|
||||
"entryType": "function",
|
||||
"jsdocTags": [],
|
||||
"rawComment": "/**\n * Transform the free-form body into a serialized format suitable for\n * transmission to the server.\n */"
|
||||
},
|
||||
"entryType": "function",
|
||||
"description": "Transform the free-form body into a serialized format suitable for\ntransmission to the server.",
|
||||
"jsdocTags": [],
|
||||
"rawComment": "/**\n * Transform the free-form body into a serialized format suitable for\n * transmission to the server.\n */",
|
||||
"memberType": "method",
|
||||
"memberTags": []
|
||||
},
|
||||
{
|
||||
"name": "detectContentTypeHeader",
|
||||
"signatures": [
|
||||
{
|
||||
"name": "detectContentTypeHeader",
|
||||
"entryType": "function",
|
||||
"description": "Examine the body and attempt to infer an appropriate MIME type\nfor it.\n\nIf no such type can be inferred, this method will return `null`.",
|
||||
"generics": [],
|
||||
"isNewType": false,
|
||||
"jsdocTags": [],
|
||||
"params": [],
|
||||
"rawComment": "/**\n * Examine the body and attempt to infer an appropriate MIME type\n * for it.\n *\n * If no such type can be inferred, this method will return `null`.\n */",
|
||||
"returnType": "string | null"
|
||||
}
|
||||
],
|
||||
"implementation": {
|
||||
"params": [],
|
||||
"isNewType": false,
|
||||
"returnType": "string | null",
|
||||
"generics": [],
|
||||
"name": "detectContentTypeHeader",
|
||||
"description": "Examine the body and attempt to infer an appropriate MIME type\nfor it.\n\nIf no such type can be inferred, this method will return `null`.",
|
||||
"entryType": "function",
|
||||
"jsdocTags": [],
|
||||
"rawComment": "/**\n * Examine the body and attempt to infer an appropriate MIME type\n * for it.\n *\n * If no such type can be inferred, this method will return `null`.\n */"
|
||||
},
|
||||
"entryType": "function",
|
||||
"description": "Examine the body and attempt to infer an appropriate MIME type\nfor it.\n\nIf no such type can be inferred, this method will return `null`.",
|
||||
"jsdocTags": [],
|
||||
"rawComment": "/**\n * Examine the body and attempt to infer an appropriate MIME type\n * for it.\n *\n * If no such type can be inferred, this method will return `null`.\n */",
|
||||
"memberType": "method",
|
||||
"memberTags": []
|
||||
},
|
||||
{
|
||||
"name": "clone",
|
||||
"signatures": [
|
||||
{
|
||||
"name": "clone",
|
||||
"entryType": "function",
|
||||
"description": "",
|
||||
"generics": [],
|
||||
"isNewType": false,
|
||||
"jsdocTags": [],
|
||||
"params": [],
|
||||
"rawComment": "",
|
||||
"returnType": "HttpRequest<T>"
|
||||
},
|
||||
{
|
||||
"name": "clone",
|
||||
"entryType": "function",
|
||||
"description": "",
|
||||
"generics": [],
|
||||
"isNewType": false,
|
||||
"jsdocTags": [],
|
||||
"params": [
|
||||
{
|
||||
"name": "update",
|
||||
"description": "",
|
||||
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; body?: T | null | undefined; method?: string | undefined; url?: string | undefined; setHeaders?: { [name: string]: string | string[]; } | undefined; setParams?: { [param: string]: string; } | undefined; }",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
}
|
||||
],
|
||||
"rawComment": "",
|
||||
"returnType": "HttpRequest<T>"
|
||||
},
|
||||
{
|
||||
"name": "clone",
|
||||
"entryType": "function",
|
||||
"description": "",
|
||||
"generics": [{"name": "V"}],
|
||||
"isNewType": false,
|
||||
"jsdocTags": [],
|
||||
"params": [
|
||||
{
|
||||
"name": "update",
|
||||
"description": "",
|
||||
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; body?: V | null | undefined; method?: string | undefined; url?: string | undefined; setHeaders?: { [name: string]: string | string[]; } | undefined; setParams?: { [param: string]: string; } | undefined; }",
|
||||
"isOptional": false,
|
||||
"isRestParam": false
|
||||
}
|
||||
],
|
||||
"rawComment": "",
|
||||
"returnType": "HttpRequest<V>"
|
||||
}
|
||||
],
|
||||
"implementation": {
|
||||
"params": [
|
||||
{
|
||||
"name": "update",
|
||||
"description": "",
|
||||
"type": "{ headers?: HttpHeaders | undefined; context?: HttpContext | undefined; reportProgress?: boolean | undefined; params?: HttpParams | undefined; responseType?: \"arraybuffer\" | \"blob\" | \"text\" | \"json\" | undefined; withCredentials?: boolean | undefined; transferCache?: boolean | { includeHeaders?: string[] | undefined; } | undefined; body?: any; method?: string | undefined; url?: string | undefined; setHeaders?: { [name: string]: string | string[]; } | undefined; setParams?: { [param: string]: string; } | undefined; }",
|
||||
"isOptional": true,
|
||||
"isRestParam": false
|
||||
}
|
||||
],
|
||||
"isNewType": false,
|
||||
"returnType": "HttpRequest<any>",
|
||||
"generics": [],
|
||||
"name": "clone",
|
||||
"description": "",
|
||||
"entryType": "function",
|
||||
"jsdocTags": [],
|
||||
"rawComment": ""
|
||||
},
|
||||
"entryType": "function",
|
||||
"description": "",
|
||||
"jsdocTags": [],
|
||||
"rawComment": "",
|
||||
"memberType": "method",
|
||||
"memberTags": []
|
||||
}
|
||||
],
|
||||
"generics": [{"name": "T"}],
|
||||
"description": "An outgoing HTTP request with an optional typed body.\n\n`HttpRequest` represents an outgoing request, including URL, method,\nheaders, body, and other request configuration options. Instances should be\nassumed to be immutable. To modify a `HttpRequest`, the `clone`\nmethod should be used.",
|
||||
"jsdocTags": [{"name": "publicApi", "comment": ""}],
|
||||
"rawComment": "/**\n * An outgoing HTTP request with an optional typed body.\n *\n * `HttpRequest` represents an outgoing request, including URL, method,\n * headers, body, and other request configuration options. Instances should be\n * assumed to be immutable. To modify a `HttpRequest`, the `clone`\n * method should be used.\n *\n * @publicApi\n */",
|
||||
"implements": [],
|
||||
"source": {
|
||||
"filePath": "/packages/common/http/src/request.ts",
|
||||
"startLine": 131,
|
||||
"endLine": 578
|
||||
}
|
||||
}
|
||||
],
|
||||
"symbols": [
|
||||
|
|
|
|||
|
|
@ -117,6 +117,8 @@ class ClassExtractor {
|
|||
return this.extractClassProperty(memberDeclaration);
|
||||
} else if (ts.isAccessor(memberDeclaration)) {
|
||||
return this.extractGetterSetter(memberDeclaration);
|
||||
} else if (ts.isConstructorDeclaration(memberDeclaration)) {
|
||||
return this.extractConstructor(memberDeclaration);
|
||||
}
|
||||
|
||||
// We only expect methods, properties, and accessors. If we encounter something else,
|
||||
|
|
@ -180,6 +182,19 @@ class ClassExtractor {
|
|||
};
|
||||
}
|
||||
|
||||
protected extractConstructor(constructorDeclaration: ts.ConstructorDeclaration): MethodEntry {
|
||||
const functionExtractor = new FunctionExtractor(
|
||||
'constructor',
|
||||
constructorDeclaration,
|
||||
this.typeChecker,
|
||||
);
|
||||
return {
|
||||
...functionExtractor.extract(),
|
||||
memberType: MemberType.Method,
|
||||
memberTags: this.getMemberTags(constructorDeclaration),
|
||||
};
|
||||
}
|
||||
|
||||
protected extractInheritance(
|
||||
declaration: ClassDeclaration & ClassDeclarationLike,
|
||||
): string | undefined {
|
||||
|
|
@ -211,7 +226,9 @@ class ClassExtractor {
|
|||
}
|
||||
|
||||
/** Gets the tags for a member (protected, readonly, static, etc.) */
|
||||
protected getMemberTags(member: MethodLike | PropertyLike): MemberTags[] {
|
||||
protected getMemberTags(
|
||||
member: MethodLike | PropertyLike | ts.ConstructorDeclaration,
|
||||
): MemberTags[] {
|
||||
const tags: MemberTags[] = this.getMemberTagsFromModifiers(member.modifiers ?? []);
|
||||
|
||||
if (member.questionToken) {
|
||||
|
|
@ -248,6 +265,7 @@ class ClassExtractor {
|
|||
// classes may narrow types or add method overloads.
|
||||
const type = this.typeChecker.getTypeAtLocation(this.declaration);
|
||||
const members = type.getProperties();
|
||||
const constructor = type.getSymbol()?.members?.get(ts.InternalSymbolName.Constructor);
|
||||
|
||||
// While the properties of the declaration type represent the properties that exist
|
||||
// on a class *instance*, static members are properties on the class symbol itself.
|
||||
|
|
@ -255,7 +273,7 @@ class ClassExtractor {
|
|||
const staticMembers = typeOfConstructor.getProperties();
|
||||
|
||||
const result: MemberElement[] = [];
|
||||
for (const member of [...members, ...staticMembers]) {
|
||||
for (const member of [...(constructor ? [constructor] : []), ...members, ...staticMembers]) {
|
||||
// A member may have multiple declarations in the case of function overloads.
|
||||
const memberDeclarations = this.filterMethodOverloads(member.getDeclarations() ?? []);
|
||||
for (const memberDeclaration of memberDeclarations) {
|
||||
|
|
@ -272,17 +290,23 @@ class ClassExtractor {
|
|||
private filterMethodOverloads(declarations: ts.Declaration[]): ts.Declaration[] {
|
||||
return declarations.filter((declaration, index) => {
|
||||
// Check if the declaration is a function or method
|
||||
if (ts.isFunctionDeclaration(declaration) || ts.isMethodDeclaration(declaration)) {
|
||||
if (
|
||||
ts.isFunctionDeclaration(declaration) ||
|
||||
ts.isMethodDeclaration(declaration) ||
|
||||
ts.isConstructorDeclaration(declaration)
|
||||
) {
|
||||
// TypeScript ensures that all declarations for a given abstract method appear consecutively.
|
||||
const nextDeclaration = declarations[index + 1];
|
||||
const isNextAbstractMethodWithSameName =
|
||||
const isNextMethodWithSameName =
|
||||
nextDeclaration &&
|
||||
ts.isMethodDeclaration(nextDeclaration) &&
|
||||
nextDeclaration.name.getText() === declaration.name?.getText();
|
||||
((ts.isMethodDeclaration(nextDeclaration) &&
|
||||
nextDeclaration.name.getText() === declaration.name?.getText()) ||
|
||||
(ts.isConstructorDeclaration(nextDeclaration) &&
|
||||
ts.isConstructorDeclaration(declaration)));
|
||||
|
||||
// Return only the last occurrence of an abstract method to avoid overload duplication.
|
||||
// Return only the last occurrence of a method to avoid overload duplication.
|
||||
// Subsequent overloads or implementations are handled separately by the function extractor.
|
||||
return !isNextAbstractMethodWithSameName;
|
||||
return !isNextMethodWithSameName;
|
||||
}
|
||||
|
||||
// Include non-method declarations, such as properties, without filtering.
|
||||
|
|
@ -326,6 +350,11 @@ class ClassExtractor {
|
|||
* - The member is marked as internal via JSDoc.
|
||||
*/
|
||||
private isMemberExcluded(member: MemberElement): boolean {
|
||||
if (ts.isConstructorDeclaration(member)) {
|
||||
// A constructor has no name
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
!member.name ||
|
||||
!this.isDocumentableMember(member) ||
|
||||
|
|
@ -345,6 +374,7 @@ class ClassExtractor {
|
|||
this.isMethod(member) ||
|
||||
this.isProperty(member) ||
|
||||
ts.isAccessor(member) ||
|
||||
ts.isConstructorDeclaration(member) ||
|
||||
// Signatures are documentable if they are part of an interface.
|
||||
ts.isCallSignatureDeclaration(member)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import ts from 'typescript';
|
||||
|
||||
import {EntryType, FunctionEntry, ParameterEntry} from './entities';
|
||||
import {EntryType, FunctionEntry, FunctionSignatureMetadata, ParameterEntry} from './entities';
|
||||
import {extractGenerics} from './generics_extractor';
|
||||
import {extractJsDocDescription, extractJsDocTags, extractRawJsDoc} from './jsdoc_extractor';
|
||||
import {extractResolvedTypeString} from './type_extractor';
|
||||
|
|
@ -18,7 +18,8 @@ export type FunctionLike =
|
|||
| ts.MethodDeclaration
|
||||
| ts.MethodSignature
|
||||
| ts.CallSignatureDeclaration
|
||||
| ts.ConstructSignatureDeclaration;
|
||||
| ts.ConstructSignatureDeclaration
|
||||
| ts.ConstructorDeclaration;
|
||||
|
||||
export class FunctionExtractor {
|
||||
constructor(
|
||||
|
|
@ -45,7 +46,9 @@ export class FunctionExtractor {
|
|||
this.exportDeclaration;
|
||||
|
||||
const type = this.typeChecker.getTypeAtLocation(this.exportDeclaration);
|
||||
const overloads = extractCallSignatures(this.name, this.typeChecker, type);
|
||||
const overloads = ts.isConstructorDeclaration(this.exportDeclaration)
|
||||
? constructorOverloads(this.exportDeclaration, this.typeChecker)
|
||||
: extractCallSignatures(this.name, this.typeChecker, type);
|
||||
const jsdocsTags = extractJsDocTags(implementation);
|
||||
const description = extractJsDocDescription(implementation);
|
||||
|
||||
|
|
@ -72,6 +75,32 @@ export class FunctionExtractor {
|
|||
}
|
||||
}
|
||||
|
||||
function constructorOverloads(
|
||||
constructorDeclaration: ts.ConstructorDeclaration,
|
||||
typeChecker: ts.TypeChecker,
|
||||
) {
|
||||
const classDeclaration = constructorDeclaration.parent;
|
||||
const constructorNode = classDeclaration.members.filter(
|
||||
(member): member is ts.ConstructorDeclaration => {
|
||||
return ts.isConstructorDeclaration(member) && !member.body;
|
||||
},
|
||||
);
|
||||
|
||||
return constructorNode.map((n): FunctionSignatureMetadata => {
|
||||
return {
|
||||
name: 'constructor',
|
||||
params: extractAllParams(n.parameters, typeChecker),
|
||||
returnType: typeChecker.getTypeAtLocation(classDeclaration)?.symbol.name,
|
||||
description: extractJsDocDescription(n),
|
||||
entryType: EntryType.Function,
|
||||
jsdocTags: extractJsDocTags(n),
|
||||
rawComment: extractRawJsDoc(n),
|
||||
generics: extractGenerics(n),
|
||||
isNewType: false,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/** Extracts parameters of the given parameter declaration AST nodes. */
|
||||
export function extractAllParams(
|
||||
params: ts.NodeArray<ts.ParameterDeclaration>,
|
||||
|
|
@ -90,14 +119,19 @@ export function extractAllParams(
|
|||
function filterSignatureDeclarations(signatures: readonly ts.Signature[]) {
|
||||
const result: Array<{
|
||||
signature: ts.Signature;
|
||||
decl: ts.FunctionDeclaration | ts.CallSignatureDeclaration | ts.MethodDeclaration;
|
||||
decl:
|
||||
| ts.FunctionDeclaration
|
||||
| ts.CallSignatureDeclaration
|
||||
| ts.MethodDeclaration
|
||||
| ts.ConstructSignatureDeclaration;
|
||||
}> = [];
|
||||
for (const signature of signatures) {
|
||||
const decl = signature.getDeclaration();
|
||||
if (
|
||||
ts.isFunctionDeclaration(decl) ||
|
||||
ts.isCallSignatureDeclaration(decl) ||
|
||||
ts.isMethodDeclaration(decl)
|
||||
ts.isMethodDeclaration(decl) ||
|
||||
ts.isConstructSignatureDeclaration(decl)
|
||||
) {
|
||||
result.push({signature, decl});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,61 @@ runInEachFileSystem(() => {
|
|||
expect(customSliderEntry.entryType).toBe(EntryType.UndecoratedClass);
|
||||
});
|
||||
|
||||
it('should extract class constructor', () => {
|
||||
env.write(
|
||||
'index.ts',
|
||||
`
|
||||
export class UserProfile {
|
||||
constructor(foo: number) {}
|
||||
}
|
||||
`,
|
||||
);
|
||||
|
||||
const docs: DocEntry[] = env.driveDocsExtraction('index.ts');
|
||||
const classEntry = docs[0] as ClassEntry;
|
||||
expect(classEntry.members.length).toBe(1);
|
||||
|
||||
const methodEntry = classEntry.members[0] as MethodEntry;
|
||||
expect(methodEntry.memberType).toBe(MemberType.Method);
|
||||
expect(methodEntry.name).toBe('constructor');
|
||||
expect(methodEntry.implementation.params.length).toBe(1);
|
||||
expect(methodEntry.implementation.params[0].name).toBe('foo');
|
||||
expect(methodEntry.implementation.params[0].type).toBe('number');
|
||||
});
|
||||
|
||||
it('should extract class constructor with overloads', () => {
|
||||
env.write(
|
||||
'index.ts',
|
||||
`
|
||||
export class UserProfile {
|
||||
constructor(value: boolean);
|
||||
constructor(value: number);
|
||||
constructor(value: number | boolean | string) { }
|
||||
}
|
||||
`,
|
||||
);
|
||||
|
||||
const docs: DocEntry[] = env.driveDocsExtraction('index.ts');
|
||||
const classEntry = docs[0] as ClassEntry;
|
||||
expect(classEntry.members.length).toBe(1);
|
||||
|
||||
const constructorEntry = classEntry.members[0] as MethodEntry;
|
||||
|
||||
expect(constructorEntry.signatures.length).toBe(2);
|
||||
|
||||
const [booleanOverloadEntry, numberOverloadEntry] = constructorEntry.signatures;
|
||||
|
||||
expect(booleanOverloadEntry.name).toBe('constructor');
|
||||
expect(booleanOverloadEntry.params.length).toBe(1);
|
||||
expect(booleanOverloadEntry.params[0].type).toBe('boolean');
|
||||
expect(booleanOverloadEntry.returnType).toBe('UserProfile');
|
||||
|
||||
expect(numberOverloadEntry.name).toBe('constructor');
|
||||
expect(numberOverloadEntry.params.length).toBe(1);
|
||||
expect(numberOverloadEntry.params[0].type).toBe('number');
|
||||
expect(numberOverloadEntry.returnType).toBe('UserProfile');
|
||||
});
|
||||
|
||||
it('should extract class members', () => {
|
||||
env.write(
|
||||
'index.ts',
|
||||
|
|
@ -650,9 +705,14 @@ runInEachFileSystem(() => {
|
|||
expect(docs.length).toBe(1);
|
||||
|
||||
const classEntry = docs[0] as ClassEntry;
|
||||
expect(classEntry.members.length).toBe(2);
|
||||
|
||||
const [myPropEntry, fooEntry] = classEntry.members as PropertyEntry[];
|
||||
// constructor, myProp, foo (others are non-public)
|
||||
expect(classEntry.members.length).toBe(3);
|
||||
|
||||
const [constructorEntry, myPropEntry, fooEntry] = classEntry.members as PropertyEntry[];
|
||||
|
||||
expect(constructorEntry.name).toBe('constructor');
|
||||
expect(constructorEntry.memberType).toBe(MemberType.Method);
|
||||
|
||||
expect(myPropEntry.name).toBe('myProp');
|
||||
expect(myPropEntry.memberType).toBe(MemberType.Property);
|
||||
|
|
|
|||
Loading…
Reference in a new issue