mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-14 18:43:31 +01:00
feat(api-extractor): replace type parameters with their actual values on inherited members (#9939)
* refactor: use tokenRange for typeParams in heritage * fix: correct type param replacement
This commit is contained in:
@@ -24,14 +24,12 @@ export function ExcerptText({ model, excerpt }: ExcerptTextProps) {
|
|||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
{excerpt.spannedTokens.map((token, idx) => {
|
{excerpt.spannedTokens.map((token, idx) => {
|
||||||
// TODO: Real fix in api-extractor needed
|
|
||||||
const text = token.text.replaceAll('\n', '').replaceAll(/\s{2}$/g, '');
|
|
||||||
if (token.kind === ExcerptTokenKind.Reference) {
|
if (token.kind === ExcerptTokenKind.Reference) {
|
||||||
if (text in BuiltinDocumentationLinks) {
|
if (token.text in BuiltinDocumentationLinks) {
|
||||||
const href = BuiltinDocumentationLinks[text as keyof typeof BuiltinDocumentationLinks];
|
const href = BuiltinDocumentationLinks[token.text as keyof typeof BuiltinDocumentationLinks];
|
||||||
return (
|
return (
|
||||||
<DocumentationLink key={`${text}-${idx}`} href={href}>
|
<DocumentationLink key={`${token.text}-${idx}`} href={href}>
|
||||||
{text}
|
{token.text}
|
||||||
</DocumentationLink>
|
</DocumentationLink>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -45,20 +43,22 @@ export function ExcerptText({ model, excerpt }: ExcerptTextProps) {
|
|||||||
// dapi-types doesn't have routes for class members
|
// dapi-types doesn't have routes for class members
|
||||||
// so we can assume this member is for an enum
|
// so we can assume this member is for an enum
|
||||||
if (meaning === 'member' && path && 'parent' in path) href += `/enum/${path.parent}#${path.component}`;
|
if (meaning === 'member' && path && 'parent' in path) href += `/enum/${path.parent}#${path.component}`;
|
||||||
else if (meaning === 'type') href += `#${text}`;
|
else if (meaning === 'type' || meaning === 'var') href += `#${token.text}`;
|
||||||
else href += `/${meaning}/${text}`;
|
else href += `/${meaning}/${token.text}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DocumentationLink key={`${text}-${idx}`} href={href}>
|
<DocumentationLink key={`${token.text}-${idx}`} href={href}>
|
||||||
{text}
|
{token.text}
|
||||||
</DocumentationLink>
|
</DocumentationLink>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const item = model.resolveDeclarationReference(token.canonicalReference!, model).resolvedApiItem;
|
const item = token.canonicalReference
|
||||||
|
? model.resolveDeclarationReference(token.canonicalReference!, model).resolvedApiItem
|
||||||
|
: null;
|
||||||
|
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return text;
|
return token.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -68,12 +68,12 @@ export function ExcerptText({ model, excerpt }: ExcerptTextProps) {
|
|||||||
key={`${item.displayName}-${item.containerKey}-${idx}`}
|
key={`${item.displayName}-${item.containerKey}-${idx}`}
|
||||||
packageName={item.getAssociatedPackage()?.displayName.replace('@discordjs/', '')}
|
packageName={item.getAssociatedPackage()?.displayName.replace('@discordjs/', '')}
|
||||||
>
|
>
|
||||||
{text}
|
{token.text}
|
||||||
</ItemLink>
|
</ItemLink>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return text.replace(/import\("discord-api-types(?:\/v\d+)?"\)\./, '');
|
return token.text.replace(/import\("discord-api-types(?:\/v\d+)?"\)\./, '');
|
||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ export function TableOfContentItems({ serializedMembers }: TableOfContentsItemPr
|
|||||||
<div className="flex flex-row place-items-center gap-4">
|
<div className="flex flex-row place-items-center gap-4">
|
||||||
<VscSymbolEvent size={20} />
|
<VscSymbolEvent size={20} />
|
||||||
<div className="p-3 pl-0">
|
<div className="p-3 pl-0">
|
||||||
<span className="font-semibold">Properties</span>
|
<span className="font-semibold">Events</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{eventItems}
|
{eventItems}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-loop-func */
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||||
// See LICENSE in the project root for license information.
|
// See LICENSE in the project root for license information.
|
||||||
|
|
||||||
|
import { TSDocConfiguration } from '@microsoft/tsdoc';
|
||||||
import type { DeclarationReference } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference.js';
|
import type { DeclarationReference } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference.js';
|
||||||
import { InternalError } from '@rushstack/node-core-library';
|
import { InternalError } from '@rushstack/node-core-library';
|
||||||
import type { ApiDeclaredItem } from '../index.js';
|
import type { IExcerptToken, IExcerptTokenRange } from '../index.js';
|
||||||
|
import { ApiDeclaredItem } from '../index.js';
|
||||||
|
import type { IApiDeclaredItemJson } from '../items/ApiDeclaredItem.js';
|
||||||
import {
|
import {
|
||||||
ApiItem,
|
ApiItem,
|
||||||
apiItem_onParentChanged,
|
apiItem_onParentChanged,
|
||||||
@@ -15,11 +19,12 @@ import {
|
|||||||
import type { ApiClass } from '../model/ApiClass.js';
|
import type { ApiClass } from '../model/ApiClass.js';
|
||||||
import type { ApiInterface } from '../model/ApiInterface.js';
|
import type { ApiInterface } from '../model/ApiInterface.js';
|
||||||
import type { ApiModel } from '../model/ApiModel.js';
|
import type { ApiModel } from '../model/ApiModel.js';
|
||||||
import type { DeserializerContext } from '../model/DeserializerContext.js';
|
import { ApiJsonSchemaVersion, type DeserializerContext } from '../model/DeserializerContext.js';
|
||||||
import type { HeritageType } from '../model/HeritageType.js';
|
import type { HeritageType } from '../model/HeritageType.js';
|
||||||
import type { IResolveDeclarationReferenceResult } from '../model/ModelReferenceResolver.js';
|
import type { IResolveDeclarationReferenceResult } from '../model/ModelReferenceResolver.js';
|
||||||
import { ApiNameMixin } from './ApiNameMixin.js';
|
import { ApiNameMixin } from './ApiNameMixin.js';
|
||||||
import { type ExcerptToken, ExcerptTokenKind } from './Excerpt.js';
|
import type { ExcerptToken } from './Excerpt.js';
|
||||||
|
import { ExcerptTokenKind } from './Excerpt.js';
|
||||||
import { type IFindApiItemsResult, type IFindApiItemsMessage, FindApiItemsMessageId } from './IFindApiItemsResult.js';
|
import { type IFindApiItemsResult, type IFindApiItemsMessage, FindApiItemsMessageId } from './IFindApiItemsResult.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,9 +42,13 @@ export interface IApiItemContainerJson extends IApiItemJson {
|
|||||||
preserveMemberOrder?: boolean;
|
preserveMemberOrder?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ExcerptTokenRangeInDeclaredItem {
|
||||||
|
item: ApiDeclaredItem;
|
||||||
|
range: IExcerptTokenRange;
|
||||||
|
}
|
||||||
interface IMappedTypeParameters {
|
interface IMappedTypeParameters {
|
||||||
item: ApiItem;
|
item: ApiItem;
|
||||||
mappedTypeParameters: Map<string, string>;
|
mappedTypeParameters: Map<string, ExcerptTokenRangeInDeclaredItem>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const _members: unique symbol = Symbol('ApiItemContainerMixin._members');
|
const _members: unique symbol = Symbol('ApiItemContainerMixin._members');
|
||||||
@@ -317,7 +326,7 @@ export function ApiItemContainerMixin<TBaseClass extends IApiItemConstructor>(
|
|||||||
let next: IMappedTypeParameters | undefined = { item: this, mappedTypeParameters: new Map() };
|
let next: IMappedTypeParameters | undefined = { item: this, mappedTypeParameters: new Map() };
|
||||||
|
|
||||||
while (next?.item) {
|
while (next?.item) {
|
||||||
const membersToAdd: ApiItem[] = []; /*
|
const membersToAdd: ApiItem[] = []; //*
|
||||||
const typeParams = next.mappedTypeParameters;
|
const typeParams = next.mappedTypeParameters;
|
||||||
const context: DeserializerContext = {
|
const context: DeserializerContext = {
|
||||||
apiJsonFilename: '',
|
apiJsonFilename: '',
|
||||||
@@ -325,56 +334,46 @@ export function ApiItemContainerMixin<TBaseClass extends IApiItemConstructor>(
|
|||||||
toolVersion: '',
|
toolVersion: '',
|
||||||
versionToDeserialize: ApiJsonSchemaVersion.LATEST,
|
versionToDeserialize: ApiJsonSchemaVersion.LATEST,
|
||||||
tsdocConfiguration: new TSDocConfiguration(),
|
tsdocConfiguration: new TSDocConfiguration(),
|
||||||
}; */
|
}; // */
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports, @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
|
||||||
|
const deserializerModule: typeof import('../model/Deserializer') = require('../model/Deserializer');
|
||||||
|
|
||||||
// For each member, check to see if we've already seen a member with the same name
|
// For each member, check to see if we've already seen a member with the same name
|
||||||
// previously in the inheritance tree. If so, we know we won't inherit it, and thus
|
// previously in the inheritance tree. If so, we know we won't inherit it, and thus
|
||||||
// do not add it to our `membersToAdd` array.
|
// do not add it to our `membersToAdd` array.
|
||||||
for (const member of next.item.members) {
|
for (let member of next.item.members) {
|
||||||
// We add the to-be-added members to an intermediate array instead of immediately
|
// We add the to-be-added members to an intermediate array instead of immediately
|
||||||
// to the maps themselves to support method overloads with the same name.
|
// to the maps themselves to support method overloads with the same name.
|
||||||
if (ApiNameMixin.isBaseClassOf(member)) {
|
|
||||||
if (!membersByName.has(member.name)) {
|
// This was supposed to replace type parameters with their assigned values in inheritance, but doesn't work yet
|
||||||
// This was supposed to replace type parameters with their assigned values in inheritance, but doesn't work yet
|
//*
|
||||||
/*
|
if (member instanceof ApiDeclaredItem && member.excerptTokens.some((token) => typeParams.has(token.text))) {
|
||||||
if (
|
const jsonObject: Partial<IApiItemJson> = {};
|
||||||
ApiTypeParameterListMixin.isBaseClassOf(member) &&
|
member.serializeInto(jsonObject);
|
||||||
member.typeParameters.some((param) => typeParams.has(param.name))
|
const excerptTokens = (jsonObject as IApiDeclaredItemJson).excerptTokens.map((token) => {
|
||||||
) {
|
let x: ExcerptToken | undefined;
|
||||||
const jsonObject: Partial<IApiItemJson> = {};
|
if (typeParams.has(token.text) && next?.item instanceof ApiDeclaredItem) {
|
||||||
member.serializeInto(jsonObject);
|
const originalValue = typeParams.get(token.text)!;
|
||||||
member = deserializerModule.Deserializer.deserialize(context, {
|
x = originalValue.item.excerptTokens[originalValue.range.startIndex];
|
||||||
...jsonObject,
|
|
||||||
typeParameters: (jsonObject as IApiTypeParameterListMixinJson).typeParameters.map(
|
|
||||||
({ typeParameterName, constraintTokenRange, defaultTypeTokenRange }) => ({
|
|
||||||
typeParameterName: typeParams.get(typeParameterName) ?? typeParameterName,
|
|
||||||
defaultTypeTokenRange,
|
|
||||||
constraintTokenRange,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
} as IApiTypeParameterListMixinJson);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ApiReturnTypeMixin.isBaseClassOf(member)) {
|
const excerptToken: IExcerptToken = x ? { kind: x.kind, text: x.text } : token;
|
||||||
const jsonObject: Partial<IApiItemJson> = {};
|
if (x?.canonicalReference !== undefined) {
|
||||||
member.serializeInto(jsonObject);
|
excerptToken.canonicalReference = x.canonicalReference.toString();
|
||||||
member = deserializerModule.Deserializer.deserialize(context, {
|
}
|
||||||
...(jsonObject as IApiReturnTypeMixinJson),
|
|
||||||
excerptTokens: (jsonObject as IApiDeclaredItemJson).excerptTokens.map((token) =>
|
|
||||||
token.kind === ExcerptTokenKind.Content
|
|
||||||
? {
|
|
||||||
kind: ExcerptTokenKind.Content,
|
|
||||||
text: [...typeParams.keys()].reduce(
|
|
||||||
(tok, typ) => tok.replaceAll(new RegExp(`\b${typ}\b`, 'g'), typeParams.get(typ)!),
|
|
||||||
token.text,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: token,
|
|
||||||
),
|
|
||||||
} as IApiReturnTypeMixinJson);
|
|
||||||
member[apiItem_onParentChanged](next.item);
|
|
||||||
} // */
|
|
||||||
|
|
||||||
|
return excerptToken;
|
||||||
|
});
|
||||||
|
member = deserializerModule.Deserializer.deserialize(context, {
|
||||||
|
...jsonObject,
|
||||||
|
excerptTokens,
|
||||||
|
} as IApiDeclaredItemJson);
|
||||||
|
member[apiItem_onParentChanged](next.item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ApiNameMixin.isBaseClassOf(member)) {
|
||||||
|
if (!membersByName.has(member.name)) {
|
||||||
membersToAdd.push(member);
|
membersToAdd.push(member);
|
||||||
}
|
}
|
||||||
} else if (!membersByKind.has(member.kind)) {
|
} else if (!membersByKind.has(member.kind)) {
|
||||||
@@ -478,14 +477,20 @@ export function ApiItemContainerMixin<TBaseClass extends IApiItemConstructor>(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mappedTypeParameters: Map<string, string> = new Map();
|
const mappedTypeParameters: Map<string, ExcerptTokenRangeInDeclaredItem> = new Map();
|
||||||
if (
|
if (
|
||||||
(apiItem.kind === ApiItemKind.Class || apiItem.kind === ApiItemKind.Interface) &&
|
(apiItem.kind === ApiItemKind.Class || apiItem.kind === ApiItemKind.Interface) &&
|
||||||
next.item.kind === ApiItemKind.Class
|
next.item.kind === ApiItemKind.Class
|
||||||
) {
|
) {
|
||||||
for (const [index, typeParameter] of extendsType.typeParameters?.entries() ?? []) {
|
for (const [index, key] of (apiItem as ApiClass | ApiInterface).typeParameters.entries() ?? []) {
|
||||||
const key = (apiItem as ApiClass | ApiInterface).typeParameters[index]?.name ?? '';
|
const typeParameter = extendsType.typeParameters?.[index];
|
||||||
mappedTypeParameters.set(key, typeParameter);
|
if (typeParameter)
|
||||||
|
mappedTypeParameters.set(key.name, { item: next.item as ApiDeclaredItem, range: typeParameter });
|
||||||
|
else if (key.defaultTypeExcerpt)
|
||||||
|
mappedTypeParameters.set(key.name, {
|
||||||
|
item: apiItem as ApiDeclaredItem,
|
||||||
|
range: key.defaultTypeExcerpt.tokenRange,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export interface IApiClassOptions
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IExcerptTokenRangeWithTypeParameters extends IExcerptTokenRange {
|
export interface IExcerptTokenRangeWithTypeParameters extends IExcerptTokenRange {
|
||||||
typeParameters: string[];
|
typeParameters: IExcerptTokenRange[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IApiClassJson
|
export interface IApiClassJson
|
||||||
|
|||||||
@@ -91,13 +91,18 @@ export enum ApiJsonSchemaVersion {
|
|||||||
*/
|
*/
|
||||||
V_1011 = 1_011,
|
V_1011 = 1_011,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a `fileLine`and `fileColumn` field to track source code location
|
||||||
|
*/
|
||||||
|
V_1012 = 1_012,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current latest .api.json schema version.
|
* The current latest .api.json schema version.
|
||||||
*
|
*
|
||||||
* IMPORTANT: When incrementing this number, consider whether `OLDEST_SUPPORTED` or `OLDEST_FORWARDS_COMPATIBLE`
|
* IMPORTANT: When incrementing this number, consider whether `OLDEST_SUPPORTED` or `OLDEST_FORWARDS_COMPATIBLE`
|
||||||
* should be updated.
|
* should be updated.
|
||||||
*/
|
*/
|
||||||
LATEST = V_1011,
|
LATEST = V_1012,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The oldest .api.json schema version that is still supported for backwards compatibility.
|
* The oldest .api.json schema version that is still supported for backwards compatibility.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||||
// See LICENSE in the project root for license information.
|
// See LICENSE in the project root for license information.
|
||||||
|
|
||||||
import type { Excerpt } from '../mixins/Excerpt.js';
|
import type { Excerpt, IExcerptTokenRange } from '../mixins/Excerpt.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a type referenced via an "extends" or "implements" heritage clause for a TypeScript class
|
* Represents a type referenced via an "extends" or "implements" heritage clause for a TypeScript class
|
||||||
@@ -38,9 +38,9 @@ export class HeritageType {
|
|||||||
*/
|
*/
|
||||||
public readonly excerpt: Excerpt;
|
public readonly excerpt: Excerpt;
|
||||||
|
|
||||||
public readonly typeParameters?: string[];
|
public readonly typeParameters?: IExcerptTokenRange[];
|
||||||
|
|
||||||
public constructor(excerpt: Excerpt, typeParameters: string[]) {
|
public constructor(excerpt: Excerpt, typeParameters: IExcerptTokenRange[]) {
|
||||||
this.excerpt = excerpt;
|
this.excerpt = excerpt;
|
||||||
this.typeParameters = typeParameters;
|
this.typeParameters = typeParameters;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -538,9 +538,6 @@ export class ApiModelGenerator {
|
|||||||
|
|
||||||
if (apiClass === undefined) {
|
if (apiClass === undefined) {
|
||||||
const classDeclaration: ts.ClassDeclaration = astDeclaration.declaration as ts.ClassDeclaration;
|
const classDeclaration: ts.ClassDeclaration = astDeclaration.declaration as ts.ClassDeclaration;
|
||||||
if (name === 'ActionRow') {
|
|
||||||
console.dir(classDeclaration.heritageClauses?.[0]?.types[0]?.typeArguments, { depth: 3 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
const nodesToCapture: IExcerptBuilderNodeToCapture[] = [];
|
||||||
|
|
||||||
@@ -557,9 +554,12 @@ export class ApiModelGenerator {
|
|||||||
extendsTokenRange = ExcerptBuilder.createEmptyTokenRangeWithTypeParameters();
|
extendsTokenRange = ExcerptBuilder.createEmptyTokenRangeWithTypeParameters();
|
||||||
if (heritageClause.types.length > 0) {
|
if (heritageClause.types.length > 0) {
|
||||||
extendsTokenRange.typeParameters.push(
|
extendsTokenRange.typeParameters.push(
|
||||||
...(heritageClause.types[0]?.typeArguments?.map((typeArgument) =>
|
...(heritageClause.types[0]?.typeArguments?.map((typeArgument) => {
|
||||||
ts.isTypeReferenceNode(typeArgument) ? typeArgument.typeName.getText() : '',
|
const typeArgumentTokenRange = ExcerptBuilder.createEmptyTokenRange();
|
||||||
) ?? []),
|
nodesToCapture.push({ node: typeArgument, tokenRange: typeArgumentTokenRange });
|
||||||
|
|
||||||
|
return typeArgumentTokenRange;
|
||||||
|
}) ?? []),
|
||||||
);
|
);
|
||||||
nodesToCapture.push({ node: heritageClause.types[0], tokenRange: extendsTokenRange });
|
nodesToCapture.push({ node: heritageClause.types[0], tokenRange: extendsTokenRange });
|
||||||
}
|
}
|
||||||
@@ -568,9 +568,14 @@ export class ApiModelGenerator {
|
|||||||
const implementsTokenRange: IExcerptTokenRangeWithTypeParameters =
|
const implementsTokenRange: IExcerptTokenRangeWithTypeParameters =
|
||||||
ExcerptBuilder.createEmptyTokenRangeWithTypeParameters();
|
ExcerptBuilder.createEmptyTokenRangeWithTypeParameters();
|
||||||
implementsTokenRange.typeParameters.push(
|
implementsTokenRange.typeParameters.push(
|
||||||
...(heritageClause.types[0]?.typeArguments?.map((typeArgument) =>
|
...(heritageType.typeArguments?.map((typeArgument) => {
|
||||||
ts.isTypeReferenceNode(typeArgument) ? typeArgument.typeName.getText() : '',
|
const typeArgumentTokenRange = ExcerptBuilder.createEmptyTokenRange();
|
||||||
) ?? []),
|
if (ts.isTypeReferenceNode(typeArgument)) {
|
||||||
|
nodesToCapture.push({ node: typeArgument, tokenRange: typeArgumentTokenRange });
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeArgumentTokenRange;
|
||||||
|
}) ?? []),
|
||||||
);
|
);
|
||||||
implementsTokenRanges.push(implementsTokenRange);
|
implementsTokenRanges.push(implementsTokenRange);
|
||||||
nodesToCapture.push({ node: heritageType, tokenRange: implementsTokenRange });
|
nodesToCapture.push({ node: heritageType, tokenRange: implementsTokenRange });
|
||||||
@@ -893,9 +898,14 @@ export class ApiModelGenerator {
|
|||||||
const extendsTokenRange: IExcerptTokenRangeWithTypeParameters =
|
const extendsTokenRange: IExcerptTokenRangeWithTypeParameters =
|
||||||
ExcerptBuilder.createEmptyTokenRangeWithTypeParameters();
|
ExcerptBuilder.createEmptyTokenRangeWithTypeParameters();
|
||||||
extendsTokenRange.typeParameters.push(
|
extendsTokenRange.typeParameters.push(
|
||||||
...(heritageClause.types[0]?.typeArguments?.map((typeArgument) =>
|
...(heritageType.typeArguments?.map((typeArgument) => {
|
||||||
ts.isTypeReferenceNode(typeArgument) ? typeArgument.typeName.getText() : '',
|
const typeArgumentTokenRange = ExcerptBuilder.createEmptyTokenRange();
|
||||||
) ?? []),
|
if (ts.isTypeReferenceNode(typeArgument)) {
|
||||||
|
nodesToCapture.push({ node: typeArgument, tokenRange: typeArgumentTokenRange });
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeArgumentTokenRange;
|
||||||
|
}) ?? []),
|
||||||
);
|
);
|
||||||
extendsTokenRanges.push(extendsTokenRange);
|
extendsTokenRanges.push(extendsTokenRange);
|
||||||
nodesToCapture.push({ node: heritageType, tokenRange: extendsTokenRange });
|
nodesToCapture.push({ node: heritageType, tokenRange: extendsTokenRange });
|
||||||
|
|||||||
@@ -176,14 +176,17 @@ export class ExcerptBuilder {
|
|||||||
|
|
||||||
if (span.kind === ts.SyntaxKind.Identifier) {
|
if (span.kind === ts.SyntaxKind.Identifier) {
|
||||||
const name: ts.Identifier = span.node as ts.Identifier;
|
const name: ts.Identifier = span.node as ts.Identifier;
|
||||||
if (!ExcerptBuilder._isDeclarationName(name)) {
|
canonicalReference = state.referenceGenerator.getDeclarationReferenceForIdentifier(name);
|
||||||
canonicalReference = state.referenceGenerator.getDeclarationReferenceForIdentifier(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canonicalReference) {
|
if (canonicalReference) {
|
||||||
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Reference, span.prefix, canonicalReference);
|
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Reference, span.prefix, canonicalReference);
|
||||||
} else if (ExcerptBuilder.isPrimitiveKeyword(span.node)) {
|
} else if (
|
||||||
|
ExcerptBuilder.isPrimitiveKeyword(span.node) ||
|
||||||
|
(span.node.kind === ts.SyntaxKind.Identifier &&
|
||||||
|
((ts.isTypeReferenceNode(span.node.parent) && span.node.parent.typeName === span.node) ||
|
||||||
|
(ts.isTypeParameterDeclaration(span.node.parent) && span.node.parent.name === span.node)))
|
||||||
|
) {
|
||||||
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Reference, span.prefix);
|
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Reference, span.prefix);
|
||||||
} else {
|
} else {
|
||||||
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Content, span.prefix);
|
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Content, span.prefix);
|
||||||
@@ -209,7 +212,11 @@ export class ExcerptBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (span.separator) {
|
if (span.separator) {
|
||||||
ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Content, span.separator);
|
ExcerptBuilder._appendToken(
|
||||||
|
excerptTokens,
|
||||||
|
ExcerptTokenKind.Content,
|
||||||
|
span.separator.replaceAll('\n', '').replaceAll(/\s{2}/g, ' '),
|
||||||
|
);
|
||||||
state.lastAppendedTokenIsSeparator = true;
|
state.lastAppendedTokenIsSeparator = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +342,7 @@ export class ExcerptBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} /*
|
||||||
|
|
||||||
private static _isDeclarationName(name: ts.Identifier): boolean {
|
private static _isDeclarationName(name: ts.Identifier): boolean {
|
||||||
return ExcerptBuilder._isDeclaration(name.parent) && name.parent.name === name;
|
return ExcerptBuilder._isDeclaration(name.parent) && name.parent.name === name;
|
||||||
@@ -366,5 +373,5 @@ export class ExcerptBuilder {
|
|||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} // */
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user