Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions packages/typescript/src/api/async/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2311,6 +2311,53 @@ function encodeNumberLiteralValue(value: number): number | string {
return value;
}

/**
* Filter for {@link Checker.getMembersOfType}: neutral predicates the caller combines
* to describe the members it will render (see `MemberFilter` for each field).
*/
export interface MemberFilterInput {
/** Visibilities to include; empty means all. ECMAScript private names count as private. */
visibility?: readonly ("public" | "protected" | "private")[] | undefined;
/** Member kinds to include; empty means all. */
kinds?: readonly ("property" | "accessor" | "method" | "parameterProperty")[] | undefined;
/** Drop members whose JSDoc carries any of these tags. */
excludeJsDocTags?: readonly string[] | undefined;
/**
* Drop members whose (wire-form) name matches this RE2 pattern. A pattern that is
* passed is always applied, so `""` drops every member; `undefined` means no name filter.
*/
excludeNamePattern?: string | undefined;
/**
* Which declaring types to take members from: `undefined` means all, `{}` means the
* queried type only, `{ declaringTypes }` adds members declared on those types.
* Members without a declaration (tuple elements, `length`, ...) are always kept.
*/
includeInheritedFrom?: { all?: boolean | undefined; declaringTypes?: readonly Symbol[] | undefined; } | undefined;
includeDeclaredType?: boolean | undefined;
}

/** The documentation of one symbol, as returned by {@link Checker.getSymbolDocumentations}. */
export interface SymbolDocumentation {
tags: readonly JSDocTagInfo[];
comment: string;
}

/** One member returned by {@link Checker.getMembersOfType}. */
export interface TypeMember {
symbol: Symbol;
/**
* The symbol of the type declaring this member, when it could be determined;
* members without a declaration have none.
*/
owner: Symbol | undefined;
isMethod: boolean;
isParameterProperty: boolean;
tags: readonly JSDocTagInfo[];
comment: string;
/** `getTypeOfSymbol(symbol)` for non-method members; only with `includeDeclaredType`. */
declaredType: Type | undefined;
}

export class Checker {
private snapshotId: number;
private project: Project;
Expand Down Expand Up @@ -3273,6 +3320,67 @@ export class Checker {
});
}

/**
* The JSDoc tags and documentation comment of many symbols in one round trip.
* Element i corresponds to `symbols[i]` and equals what `getJsDocTagsOfSymbol`
* and `getDocumentationCommentOfSymbol` return for that symbol.
*/
async getSymbolDocumentations(symbols: readonly Symbol[]): Promise<SymbolDocumentation[]> {
if (symbols.length === 0) {
return [];
}
const data = await this.client.apiRequest("getSymbolDocumentations", {
snapshot: this.snapshotId,
project: this.project.handle,
symbols: symbols.map(symbol => symbol.reference),
});
return data.map(d => ({ tags: d.tags ?? [], comment: d.comment ?? "" }));
}

/**
* The properties of a type that pass `filter`, each with its documentation, the
* symbol of the type declaring it and (when requested) its declared type, in one
* round trip. Designed for traversals that render every surviving member: the
* filter lets the caller describe exactly which members it will visit so no type
* is materialized for a member that would have been skipped.
*/
async getMembersOfType(type: Type, filter: MemberFilterInput = {}): Promise<TypeMember[]> {
const data = await this.client.apiRequest("getMembersOfType", {
snapshot: this.snapshotId,
project: this.project.handle,
type: type.id,
filter: {
visibility: filter.visibility ? [...filter.visibility] : undefined,
kinds: filter.kinds ? [...filter.kinds] : undefined,
excludeJsDocTags: filter.excludeJsDocTags ? [...filter.excludeJsDocTags] : undefined,
excludeNamePattern: filter.excludeNamePattern,
includeInheritedFrom: filter.includeInheritedFrom
? {
all: filter.includeInheritedFrom.all,
declaringTypes: filter.includeInheritedFrom.declaringTypes?.map(symbol => symbol.reference),
}
: undefined,
includeDeclaredType: filter.includeDeclaredType,
},
});
const members: TypeMember[] = [];
for (const m of data ?? []) {
if (!m.symbol) {
continue;
}
members.push({
symbol: this.objectRegistry.getOrCreateSymbol(m.symbol),
owner: m.owner ? this.objectRegistry.getOrCreateSymbol(m.owner) : undefined,
isMethod: m.isMethod ?? false,
isParameterProperty: m.isParameterProperty ?? false,
tags: m.tags ?? [],
comment: m.comment ?? "",
declaredType: m.declaredType ? this.objectRegistry.getOrCreateType(m.declaredType) : undefined,
});
}
return members;
}

/**
* Get the type arguments of a type reference (e.g. the `string` in `Array<string>`).
*/
Expand Down
100 changes: 100 additions & 0 deletions packages/typescript/src/api/proto.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export interface APIMethodInfo {
getTypePredicateOfSignature: APIMethod<CheckerSignatureParams, TypePredicateResponse | null>;
getBaseTypes: APIMethod<CheckerTypeParams, TypeResponse[] | null>;
getPropertiesOfType: APIMethod<CheckerTypeParams, SymbolResponse[] | null>;
getMembersOfType: APIMethod<GetMembersOfTypeParams, MemberResponse[]>;
getApparentPropertiesOfType: APIMethod<GetTypePropertyParams, SymbolResponse[]>;
getApparentType: APIMethod<GetTypePropertyParams, TypeResponse>;
getReducedType: APIMethod<GetTypePropertyParams, TypeResponse>;
Expand Down Expand Up @@ -186,6 +187,7 @@ export interface APIMethodInfo {
getExportsOfModule: APIMethod<CheckerSymbolParams, SymbolResponse[] | null>;
getMemberInModuleExports: APIMethod<GetMemberInModuleExportsParams, SymbolResponse | null>;
getJsDocTags: APIMethod<CheckerSymbolParams, JSDocTagInfo[] | null>;
getSymbolDocumentations: APIMethod<GetSymbolDocumentationsParams, SymbolDocumentation[]>;
getDocumentationComment: APIMethod<CheckerSymbolParams, string>;
isArrayType: APIMethod<CheckerTypeParams, boolean>;
isReadonlySymbol: APIMethod<CheckerSymbolParams, boolean>;
Expand Down Expand Up @@ -943,6 +945,33 @@ export interface TypePredicateResponse {
type?: TypeResponse | undefined;
}

/** GetMembersOfTypeParams are parameters for getMembersOfType. */
export interface GetMembersOfTypeParams {
snapshot: number;
project: number;
type: number;
filter: MemberFilter;
}

/**
* MemberResponse is one property of a type with the information a traversal needs to
* decide how to render it, in a single round trip.
*/
export interface MemberResponse {
symbol: SymbolResponse | null;
/**
* Owner is the symbol of the type declaring the member (see InheritedMemberFilter),
* when it could be determined; members without a declaration (tuple elements,
* `length`, ...) have none.
*/
owner?: SymbolResponse | undefined;
isMethod?: boolean | undefined;
isParameterProperty?: boolean | undefined;
tags?: JSDocTagInfo[] | undefined;
comment?: string | undefined;
declaredType?: TypeResponse | undefined;
}

/** GetPropertyOfTypeParams are parameters for getPropertyOfType (a named property of a type). */
export interface GetPropertyOfTypeParams {
snapshot: number;
Expand Down Expand Up @@ -1008,6 +1037,25 @@ export interface JSDocTagInfo {
text?: string | undefined;
}

/**
* GetSymbolDocumentationsParams are parameters for getSymbolDocumentations: the JSDoc
* tags and documentation comment of many symbols in one request.
*/
export interface GetSymbolDocumentationsParams {
snapshot: number;
project: number;
symbols: readonly SymbolReference[] | null;
}

/**
* SymbolDocumentation is one element of a getSymbolDocumentations response; it equals
* the results of getJsDocTags and getDocumentationComment for the same symbol.
*/
export interface SymbolDocumentation {
tags?: JSDocTagInfo[] | undefined;
comment?: string | undefined;
}

/** GetReferencesToSymbolInFileParams are the parameters for the getReferencesToSymbolInFile method. */
export interface GetReferencesToSymbolInFileParams {
snapshot: number;
Expand Down Expand Up @@ -1276,6 +1324,7 @@ export interface BatchRequest {
| "getLocalTypeParametersOfType"
| "getMemberInModuleExports"
| "getMembersOfSymbol"
| "getMembersOfType"
| "getMergedSymbol"
| "getModeForResolutionAtIndex"
| "getModeForUsageLocation"
Expand Down Expand Up @@ -1323,6 +1372,7 @@ export interface BatchRequest {
| "getSuggestionDiagnostics"
| "getSymbolAtLocation"
| "getSymbolAtPosition"
| "getSymbolDocumentations"
| "getSymbolOfDeclaration"
| "getSymbolOfDeclarationForChecker"
| "getSymbolOfNode"
Expand Down Expand Up @@ -1470,6 +1520,7 @@ export interface BatchResponse {
| "getLocalTypeParametersOfType"
| "getMemberInModuleExports"
| "getMembersOfSymbol"
| "getMembersOfType"
| "getMergedSymbol"
| "getModeForResolutionAtIndex"
| "getModeForUsageLocation"
Expand Down Expand Up @@ -1517,6 +1568,7 @@ export interface BatchResponse {
| "getSuggestionDiagnostics"
| "getSymbolAtLocation"
| "getSymbolAtPosition"
| "getSymbolDocumentations"
| "getSymbolOfDeclaration"
| "getSymbolOfDeclarationForChecker"
| "getSymbolOfNode"
Expand Down Expand Up @@ -1752,6 +1804,42 @@ export interface PackageId {
peerDependencies: string;
}

/**
* MemberFilter selects which properties of a type getMembersOfType returns. It is a
* set of neutral predicates the caller combines (like a WHERE clause) to describe the
* members it will render, so that no type is materialized for a member it would skip.
* Tool-specific policies (jsii's @internal/underscore convention, TypeDoc's @hidden, ...)
* are expressed by the caller, not encoded here.
*/
export interface MemberFilter {
/**
* Visibilities to include ("public", "protected", "private"); empty means all.
* ECMAScript private names (#x) count as private.
*/
visibility?: string[] | undefined;
/**
* Member kinds to include ("property", "accessor", "method", "parameterProperty",
* the last being a constructor parameter property); empty means all.
*/
kinds?: string[] | undefined;
/** Drop members whose JSDoc carries any of these tags (e.g. "internal", "deprecated"). */
excludeJsDocTags?: string[] | undefined;
/**
* Drop members whose name (in its wire form, as the client sees it) matches this
* RE2 pattern, e.g. "^_" or "^(_|prototype$)". Absent means no name filter; a
* pattern that is passed is always compiled, so the empty pattern matches every
* member.
*/
excludeNamePattern?: string | undefined;
/**
* Which declaring types to take members from. Nil means all (plain
* getPropertiesOfType semantics).
*/
includeInheritedFrom?: InheritedMemberFilter | undefined;
/** Include the declared type of each non-method member (getTypeOfSymbol). */
includeDeclaredType?: boolean | undefined;
}

export interface ImportAdderAction {
kind: "importSymbol";
symbol?: SymbolReference | undefined;
Expand Down Expand Up @@ -1848,6 +1936,18 @@ export interface ModuleResolutionEntry {
result: StaticModuleResolution;
}

/**
* InheritedMemberFilter restricts members by the type that declares them: members
* declared on the queried type itself are always kept; with All every base
* contributes; otherwise only members declared on one of DeclaringTypes (by symbol)
* are kept. The declaring type is the type at the declaration's owner node (its
* parent, or grandparent for a constructor parameter property).
*/
export interface InheritedMemberFilter {
all?: boolean | undefined;
declaringTypes?: SymbolReference[] | undefined;
}

/** CompletionEntryLabelDetailsResponse holds additional label display text for a completion entry. */
export interface CompletionEntryLabelDetailsResponse {
detail?: string | undefined;
Expand Down
Loading