{"version":3,"file":"Excerpt.js","sourceRoot":"","sources":["../../src/mixins/Excerpt.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAG3D,oEAAoD;AAEpD,cAAc;AACd,IAAY,gBAUX;AAVD,WAAY,gBAAgB;IAC1B;;OAEG;IACH,uCAAmB,CAAA;IAEnB;;OAEG;IACH,2CAAuB,CAAA;AACzB,CAAC,EAVW,gBAAgB,GAAhB,wBAAgB,KAAhB,wBAAgB,QAU3B;AA8BD;;;;GAIG;AACH,MAAa,YAAY;IAKvB,YAAmB,IAAsB,EAAE,IAAY,EAAE,kBAAyC;QAChG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAElB,kGAAkG;QAClG,4FAA4F;QAC5F,kFAAkF;QAClF,IAAI,CAAC,KAAK,GAAG,wBAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;;OAGG;IACH,IAAW,kBAAkB;QAC3B,OAAO,IAAI,CAAC,mBAAmB,CAAC;IAClC,CAAC;CACF;AApCD,oCAoCC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAa,OAAO;IAqBlB,YAAmB,MAAmC,EAAE,UAA8B;QACpF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAE7B,IACE,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,CAAC;YAC9B,IAAI,CAAC,UAAU,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM;YAC7C,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,EACrD;YACA,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;SACxC;QAED,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC/F,CAAC;IAED;;OAEG;IACH,IAAW,IAAI;QACb,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE;YAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SAC7D;QACD,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;IACjE,CAAC;CACF;AApDD,0BAoDC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { DeclarationReference } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference';\nimport { Text } from '@rushstack/node-core-library';\n\n/** @public */\nexport enum ExcerptTokenKind {\n /**\n * Generic text without any special properties\n */\n Content = 'Content',\n\n /**\n * A reference to an API declaration\n */\n Reference = 'Reference'\n}\n\n/**\n * Used by {@link Excerpt} to indicate a range of indexes within an array of `ExcerptToken` objects.\n *\n * @public\n */\nexport interface IExcerptTokenRange {\n /**\n * The starting index of the span.\n */\n startIndex: number;\n\n /**\n * The index of the last member of the span, plus one.\n *\n * @remarks\n *\n * If `startIndex` and `endIndex` are the same number, then the span is empty.\n */\n endIndex: number;\n}\n\n/** @public */\nexport interface IExcerptToken {\n readonly kind: ExcerptTokenKind;\n text: string;\n canonicalReference?: string;\n}\n\n/**\n * Represents a fragment of text belonging to an {@link Excerpt} object.\n *\n * @public\n */\nexport class ExcerptToken {\n private readonly _kind: ExcerptTokenKind;\n private readonly _text: string;\n private readonly _canonicalReference: DeclarationReference | undefined;\n\n public constructor(kind: ExcerptTokenKind, text: string, canonicalReference?: DeclarationReference) {\n this._kind = kind;\n\n // Standardize the newlines across operating systems. Even though this may deviate from the actual\n // input source file that was parsed, it's useful because the newline gets serialized inside\n // a string literal in .api.json, which cannot be automatically normalized by Git.\n this._text = Text.convertToLf(text);\n this._canonicalReference = canonicalReference;\n }\n\n /**\n * Indicates the kind of token.\n */\n public get kind(): ExcerptTokenKind {\n return this._kind;\n }\n\n /**\n * The text fragment.\n */\n public get text(): string {\n return this._text;\n }\n\n /**\n * The hyperlink target for a token whose type is `ExcerptTokenKind.Reference`. For other token types,\n * this property will be `undefined`.\n */\n public get canonicalReference(): DeclarationReference | undefined {\n return this._canonicalReference;\n }\n}\n\n/**\n * The `Excerpt` class is used by {@link ApiDeclaredItem} to represent a TypeScript code fragment that may be\n * annotated with hyperlinks to declared types (and in the future, source code locations).\n *\n * @remarks\n * API Extractor's .api.json file format stores excerpts compactly as a start/end indexes into an array of tokens.\n * Every `ApiDeclaredItem` has a \"main excerpt\" corresponding to the full list of tokens. The declaration may\n * also have have \"captured\" excerpts that correspond to subranges of tokens.\n *\n * For example, if the main excerpt is:\n *\n * ```\n * function parse(s: string): Vector | undefined;\n * ```\n *\n * ...then this entire signature is the \"main excerpt\", whereas the function's return type `Vector | undefined` is a\n * captured excerpt. The `Vector` token might be a hyperlink to that API item.\n *\n * An excerpt may be empty (i.e. a token range containing zero tokens). For example, if a function's return value\n * is not explicitly declared, then the returnTypeExcerpt will be empty. By contrast, a class constructor cannot\n * have a return value, so ApiConstructor has no returnTypeExcerpt property at all.\n *\n * @public\n */\nexport class Excerpt {\n /**\n * The complete list of tokens for the source code fragment that this excerpt is based upon.\n * If this object is the main excerpt, then it will span all of the tokens; otherwise, it will correspond to\n * a range within the array.\n */\n public readonly tokens: ReadonlyArray;\n\n /**\n * Specifies the excerpt's range within the `tokens` array.\n */\n public readonly tokenRange: Readonly;\n\n /**\n * The tokens spanned by this excerpt. It is the range of the `tokens` array as specified by the `tokenRange`\n * property.\n */\n public readonly spannedTokens: ReadonlyArray;\n\n private _text: string | undefined;\n\n public constructor(tokens: ReadonlyArray, tokenRange: IExcerptTokenRange) {\n this.tokens = tokens;\n this.tokenRange = tokenRange;\n\n if (\n this.tokenRange.startIndex < 0 ||\n this.tokenRange.endIndex > this.tokens.length ||\n this.tokenRange.startIndex > this.tokenRange.endIndex\n ) {\n throw new Error('Invalid token range');\n }\n\n this.spannedTokens = this.tokens.slice(this.tokenRange.startIndex, this.tokenRange.endIndex);\n }\n\n /**\n * The excerpted text, formed by concatenating the text of the `spannedTokens` strings.\n */\n public get text(): string {\n if (this._text === undefined) {\n this._text = this.spannedTokens.map((x) => x.text).join('');\n }\n return this._text;\n }\n\n /**\n * Returns true if the excerpt is an empty range.\n */\n public get isEmpty(): boolean {\n return this.tokenRange.startIndex === this.tokenRange.endIndex;\n }\n}\n"]}