Comparing version 0.24.0-beta.3 to 0.24.0-beta.4
@@ -96,8 +96,11 @@ "use strict"; | ||
} | ||
const preValidationWarnCount = app.logger.warningCount; | ||
app.validate(project); | ||
const hadValidationWarnings = app.logger.warningCount !== preValidationWarnCount; | ||
if (app.logger.hasErrors()) { | ||
return ExitCodes.ValidationError; | ||
} | ||
if (app.options.getValue("treatWarningsAsErrors") && | ||
app.logger.hasWarnings()) { | ||
if (hadValidationWarnings && | ||
(app.options.getValue("treatWarningsAsErrors") || | ||
app.options.getValue("treatValidationWarningsAsErrors"))) { | ||
return ExitCodes.ValidationError; | ||
@@ -104,0 +107,0 @@ } |
@@ -0,2 +1,3 @@ | ||
import ts from "typescript"; | ||
import { Token } from "./lexer"; | ||
export declare function lexBlockComment(file: string, pos?: number, end?: number): Generator<Token, undefined, undefined>; | ||
export declare function lexBlockComment(file: string, pos?: number, end?: number, jsDoc?: ts.JSDoc | undefined, checker?: ts.TypeChecker | undefined): Generator<Token, undefined, undefined>; |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.lexBlockComment = void 0; | ||
const typescript_1 = __importDefault(require("typescript")); | ||
const lexer_1 = require("./lexer"); | ||
function* lexBlockComment(file, pos = 0, end = file.length) { | ||
const ReflectionSymbolId_1 = require("../../models/reflections/ReflectionSymbolId"); | ||
const symbols_1 = require("../utils/symbols"); | ||
function* lexBlockComment(file, pos = 0, end = file.length, jsDoc = undefined, checker = undefined) { | ||
// Wrapper around our real lex function to collapse adjacent text tokens. | ||
let textToken; | ||
for (const token of lexBlockComment2(file, pos, end)) { | ||
for (const token of lexBlockComment2(file, pos, end, getLinkTags(jsDoc), checker)) { | ||
if (token.kind === lexer_1.TokenSyntaxKind.Text) { | ||
@@ -31,3 +37,17 @@ if (textToken) { | ||
exports.lexBlockComment = lexBlockComment; | ||
function* lexBlockComment2(file, pos, end) { | ||
function getLinkTags(jsDoc) { | ||
const result = []; | ||
if (!jsDoc || typeof jsDoc.comment !== "object") | ||
return result; | ||
for (const part of jsDoc.comment) { | ||
switch (part.kind) { | ||
case typescript_1.default.SyntaxKind.JSDocLink: | ||
case typescript_1.default.SyntaxKind.JSDocLinkCode: | ||
case typescript_1.default.SyntaxKind.JSDocLinkPlain: | ||
result.push(part); | ||
} | ||
} | ||
return result; | ||
} | ||
function* lexBlockComment2(file, pos, end, linkTags, checker) { | ||
pos += 2; // Leading '/*' | ||
@@ -51,2 +71,3 @@ end -= 2; // Trailing '*/' | ||
let braceStartsType = false; | ||
let linkTagIndex = 0; | ||
for (;;) { | ||
@@ -176,3 +197,5 @@ if (pos >= end) { | ||
braceStartsType = true; | ||
yield makeToken(lexer_1.TokenSyntaxKind.Tag, lookahead - pos); | ||
const token = makeToken(lexer_1.TokenSyntaxKind.Tag, lookahead - pos); | ||
attachLinkTagResult(token); | ||
yield token; | ||
break; | ||
@@ -219,2 +242,20 @@ } | ||
} | ||
function attachLinkTagResult(token) { | ||
// We might need to skip link tags if someone has link tags inside of an example comment | ||
// pos-1 for opening brace, TS doesn't allow spaces between opening brace and @ sign as of 5.0.2 | ||
while (linkTagIndex < linkTags.length && | ||
linkTags[linkTagIndex].pos < token.pos - 1) { | ||
linkTagIndex++; | ||
} | ||
if (linkTagIndex < linkTags.length && | ||
linkTags[linkTagIndex].pos === token.pos - 1) { | ||
const link = linkTags[linkTagIndex]; | ||
if (link.name) { | ||
const tsTarget = checker?.getSymbolAtLocation(link.name); | ||
if (tsTarget) { | ||
token.linkTarget = new ReflectionSymbolId_1.ReflectionSymbolId((0, symbols_1.resolveAliasedSymbol)(tsTarget, checker)); | ||
} | ||
} | ||
} | ||
} | ||
function makeToken(kind, size) { | ||
@@ -221,0 +262,0 @@ const start = pos; |
@@ -5,3 +5,8 @@ import ts from "typescript"; | ||
import { CommentStyle } from "../../utils/options/declaration"; | ||
export declare function discoverComment(symbol: ts.Symbol, kind: ReflectionKind, logger: Logger, commentStyle: CommentStyle): [ts.SourceFile, ts.CommentRange[]] | undefined; | ||
export declare function discoverSignatureComment(declaration: ts.SignatureDeclaration | ts.JSDocSignature, commentStyle: CommentStyle): [ts.SourceFile, ts.CommentRange[]] | undefined; | ||
export interface DiscoveredComment { | ||
file: ts.SourceFile; | ||
ranges: ts.CommentRange[]; | ||
jsDoc: ts.JSDoc | undefined; | ||
} | ||
export declare function discoverComment(symbol: ts.Symbol, kind: ReflectionKind, logger: Logger, commentStyle: CommentStyle): DiscoveredComment | undefined; | ||
export declare function discoverSignatureComment(declaration: ts.SignatureDeclaration | ts.JSDocSignature, commentStyle: CommentStyle): DiscoveredComment | undefined; |
@@ -12,2 +12,3 @@ "use strict"; | ||
const paths_1 = require("../../utils/paths"); | ||
const assert_1 = require("assert"); | ||
// Note: This does NOT include JSDoc syntax kinds. This is important! | ||
@@ -124,3 +125,7 @@ // Comments from @typedef and @callback tags are handled specially by | ||
if (selectedDocComment) { | ||
discovered.push([decl.getSourceFile(), selectedDocComment]); | ||
discovered.push({ | ||
file: decl.getSourceFile(), | ||
ranges: selectedDocComment, | ||
jsDoc: findJsDocForComment(node, selectedDocComment), | ||
}); | ||
} | ||
@@ -136,5 +141,5 @@ } | ||
logger.warn(`${symbol.name} has multiple declarations with a comment. An arbitrary comment will be used.`); | ||
const locations = discovered.map(([sf, [{ pos }]]) => { | ||
const path = (0, paths_1.nicePath)(sf.fileName); | ||
const line = typescript_1.default.getLineAndCharacterOfPosition(sf, pos).line + 1; | ||
const locations = discovered.map(({ file, ranges: [{ pos }] }) => { | ||
const path = (0, paths_1.nicePath)(file.fileName); | ||
const line = typescript_1.default.getLineAndCharacterOfPosition(file, pos).line + 1; | ||
return `${path}:${line}`; | ||
@@ -153,2 +158,17 @@ }); | ||
} | ||
if (typescript_1.default.isJSDocSignature(node)) { | ||
const comment = node.parent.parent; | ||
(0, assert_1.ok)(typescript_1.default.isJSDoc(comment)); | ||
return { | ||
file: node.getSourceFile(), | ||
ranges: [ | ||
{ | ||
kind: typescript_1.default.SyntaxKind.MultiLineCommentTrivia, | ||
pos: comment.pos, | ||
end: comment.end, | ||
}, | ||
], | ||
jsDoc: undefined, | ||
}; | ||
} | ||
const text = node.getSourceFile().text; | ||
@@ -159,6 +179,18 @@ const comments = collectCommentRanges(typescript_1.default.getLeadingCommentRanges(text, node.pos)); | ||
if (comment) { | ||
return [node.getSourceFile(), comment]; | ||
return { | ||
file: node.getSourceFile(), | ||
ranges: comment, | ||
jsDoc: findJsDocForComment(node, comment), | ||
}; | ||
} | ||
} | ||
exports.discoverSignatureComment = discoverSignatureComment; | ||
function findJsDocForComment(node, ranges) { | ||
if (ranges[0].kind === typescript_1.default.SyntaxKind.MultiLineCommentTrivia) { | ||
const jsDocs = typescript_1.default | ||
.getJSDocCommentsAndTags(node) | ||
.map((doc) => typescript_1.default.findAncestor(doc, typescript_1.default.isJSDoc)); | ||
return jsDocs.find((doc) => doc.pos === ranges[0].pos); | ||
} | ||
} | ||
/** | ||
@@ -165,0 +197,0 @@ * Check whether the given module declaration is the topmost. |
@@ -10,4 +10,4 @@ import ts from "typescript"; | ||
} | ||
export declare function getComment(symbol: ts.Symbol, kind: ReflectionKind, config: CommentParserConfig, logger: Logger, commentStyle: CommentStyle): Comment | undefined; | ||
export declare function getSignatureComment(declaration: ts.SignatureDeclaration | ts.JSDocSignature, config: CommentParserConfig, logger: Logger, commentStyle: CommentStyle): Comment | undefined; | ||
export declare function getJsDocComment(declaration: ts.JSDocPropertyLikeTag | ts.JSDocCallbackTag | ts.JSDocTypedefTag | ts.JSDocTemplateTag | ts.JSDocEnumTag, config: CommentParserConfig, logger: Logger): Comment | undefined; | ||
export declare function getComment(symbol: ts.Symbol, kind: ReflectionKind, config: CommentParserConfig, logger: Logger, commentStyle: CommentStyle, checker: ts.TypeChecker): Comment | undefined; | ||
export declare function getSignatureComment(declaration: ts.SignatureDeclaration | ts.JSDocSignature, config: CommentParserConfig, logger: Logger, commentStyle: CommentStyle, checker: ts.TypeChecker): Comment | undefined; | ||
export declare function getJsDocComment(declaration: ts.JSDocPropertyLikeTag | ts.JSDocCallbackTag | ts.JSDocTypedefTag | ts.JSDocTemplateTag | ts.JSDocEnumTag, config: CommentParserConfig, logger: Logger, checker: ts.TypeChecker): Comment | undefined; |
@@ -22,6 +22,6 @@ "use strict"; | ||
const commentCache = new WeakMap(); | ||
function getCommentWithCache(discovered, config, logger) { | ||
function getCommentWithCache(discovered, config, logger, checker) { | ||
if (!discovered) | ||
return; | ||
const [file, ranges] = discovered; | ||
const { file, ranges, jsDoc } = discovered; | ||
const cache = commentCache.get(file) || new Map(); | ||
@@ -34,3 +34,3 @@ if (cache?.has(ranges[0].pos)) { | ||
case typescript_1.default.SyntaxKind.MultiLineCommentTrivia: | ||
comment = (0, parser_1.parseComment)((0, blockLexer_1.lexBlockComment)(file.text, ranges[0].pos, ranges[0].end), config, file, logger); | ||
comment = (0, parser_1.parseComment)((0, blockLexer_1.lexBlockComment)(file.text, ranges[0].pos, ranges[0].end, jsDoc, checker), config, file, logger); | ||
break; | ||
@@ -47,4 +47,4 @@ case typescript_1.default.SyntaxKind.SingleLineCommentTrivia: | ||
} | ||
function getCommentImpl(commentSource, config, logger, moduleComment) { | ||
const comment = getCommentWithCache(commentSource, config, logger); | ||
function getCommentImpl(commentSource, config, logger, moduleComment, checker) { | ||
const comment = getCommentWithCache(commentSource, config, logger, checker); | ||
if (moduleComment && comment) { | ||
@@ -67,11 +67,11 @@ // Module comment, make sure it is tagged with @packageDocumentation or @module. | ||
} | ||
function getComment(symbol, kind, config, logger, commentStyle) { | ||
function getComment(symbol, kind, config, logger, commentStyle, checker) { | ||
const declarations = symbol.declarations || []; | ||
if (declarations.length && | ||
declarations.every((d) => jsDocCommentKinds.includes(d.kind))) { | ||
return getJsDocComment(declarations[0], config, logger); | ||
return getJsDocComment(declarations[0], config, logger, checker); | ||
} | ||
const comment = getCommentImpl((0, discovery_1.discoverComment)(symbol, kind, logger, commentStyle), config, logger, declarations.some(typescript_1.default.isSourceFile)); | ||
const comment = getCommentImpl((0, discovery_1.discoverComment)(symbol, kind, logger, commentStyle), config, logger, declarations.some(typescript_1.default.isSourceFile), checker); | ||
if (!comment && kind === models_1.ReflectionKind.Property) { | ||
return getConstructorParamPropertyComment(symbol, config, logger, commentStyle); | ||
return getConstructorParamPropertyComment(symbol, config, logger, commentStyle, checker); | ||
} | ||
@@ -81,3 +81,3 @@ return comment; | ||
exports.getComment = getComment; | ||
function getConstructorParamPropertyComment(symbol, config, logger, commentStyle) { | ||
function getConstructorParamPropertyComment(symbol, config, logger, commentStyle, checker) { | ||
const decl = symbol.declarations?.find(typescript_1.default.isParameter); | ||
@@ -87,3 +87,3 @@ if (!decl) | ||
const ctor = decl.parent; | ||
const comment = getSignatureComment(ctor, config, logger, commentStyle); | ||
const comment = getSignatureComment(ctor, config, logger, commentStyle, checker); | ||
const paramTag = comment?.getIdentifiedTag(symbol.name, "@param"); | ||
@@ -94,7 +94,7 @@ if (paramTag) { | ||
} | ||
function getSignatureComment(declaration, config, logger, commentStyle) { | ||
return getCommentImpl((0, discovery_1.discoverSignatureComment)(declaration, commentStyle), config, logger, false); | ||
function getSignatureComment(declaration, config, logger, commentStyle, checker) { | ||
return getCommentImpl((0, discovery_1.discoverSignatureComment)(declaration, commentStyle), config, logger, false, checker); | ||
} | ||
exports.getSignatureComment = getSignatureComment; | ||
function getJsDocComment(declaration, config, logger) { | ||
function getJsDocComment(declaration, config, logger, checker) { | ||
const file = declaration.getSourceFile(); | ||
@@ -107,5 +107,5 @@ // First, get the whole comment. We know we'll need all of it. | ||
// Then parse it. | ||
const comment = getCommentWithCache([ | ||
const comment = getCommentWithCache({ | ||
file, | ||
[ | ||
ranges: [ | ||
{ | ||
@@ -117,3 +117,4 @@ kind: typescript_1.default.SyntaxKind.MultiLineCommentTrivia, | ||
], | ||
], config, logger); | ||
jsDoc: parent, | ||
}, config, logger, checker); | ||
// And pull out the tag we actually care about. | ||
@@ -120,0 +121,0 @@ if (typescript_1.default.isJSDocEnumTag(declaration)) { |
@@ -0,1 +1,2 @@ | ||
import type { ReflectionSymbolId } from "../../models"; | ||
export declare enum TokenSyntaxKind { | ||
@@ -14,2 +15,3 @@ Text = "text", | ||
pos: number; | ||
linkTarget?: ReflectionSymbolId; | ||
} |
@@ -8,3 +8,3 @@ import { Comment, CommentDisplayPart, Reflection } from "../../models"; | ||
export type ExternalSymbolResolver = (ref: DeclarationReference, refl: Reflection, part: Readonly<CommentDisplayPart> | undefined) => ExternalResolveResult | string | undefined; | ||
export declare function resolveLinks(comment: Comment, reflection: Reflection, externalResolver: ExternalSymbolResolver): void; | ||
export declare function resolvePartLinks(reflection: Reflection, parts: readonly CommentDisplayPart[], externalResolver: ExternalSymbolResolver): CommentDisplayPart[]; | ||
export declare function resolveLinks(comment: Comment, reflection: Reflection, externalResolver: ExternalSymbolResolver, useTsResolution: boolean): void; | ||
export declare function resolvePartLinks(reflection: Reflection, parts: readonly CommentDisplayPart[], externalResolver: ExternalSymbolResolver, useTsResolution: boolean): CommentDisplayPart[]; |
@@ -12,17 +12,17 @@ "use strict"; | ||
const urlPrefix = /^(http|ftp)s?:\/\//; | ||
function resolveLinks(comment, reflection, externalResolver) { | ||
comment.summary = resolvePartLinks(reflection, comment.summary, externalResolver); | ||
function resolveLinks(comment, reflection, externalResolver, useTsResolution) { | ||
comment.summary = resolvePartLinks(reflection, comment.summary, externalResolver, useTsResolution); | ||
for (const tag of comment.blockTags) { | ||
tag.content = resolvePartLinks(reflection, tag.content, externalResolver); | ||
tag.content = resolvePartLinks(reflection, tag.content, externalResolver, useTsResolution); | ||
} | ||
if (reflection instanceof models_1.DeclarationReflection && reflection.readme) { | ||
reflection.readme = resolvePartLinks(reflection, reflection.readme, externalResolver); | ||
reflection.readme = resolvePartLinks(reflection, reflection.readme, externalResolver, useTsResolution); | ||
} | ||
} | ||
exports.resolveLinks = resolveLinks; | ||
function resolvePartLinks(reflection, parts, externalResolver) { | ||
return parts.flatMap((part) => processPart(reflection, part, externalResolver)); | ||
function resolvePartLinks(reflection, parts, externalResolver, useTsResolution) { | ||
return parts.flatMap((part) => processPart(reflection, part, externalResolver, useTsResolution)); | ||
} | ||
exports.resolvePartLinks = resolvePartLinks; | ||
function processPart(reflection, part, externalResolver) { | ||
function processPart(reflection, part, externalResolver, useTsResolution) { | ||
if (part.kind === "inline-tag") { | ||
@@ -32,3 +32,3 @@ if (part.tag === "@link" || | ||
part.tag === "@linkplain") { | ||
return resolveLinkTag(reflection, part, externalResolver); | ||
return resolveLinkTag(reflection, part, externalResolver, useTsResolution); | ||
} | ||
@@ -38,3 +38,4 @@ } | ||
} | ||
function resolveLinkTag(reflection, part, externalResolver) { | ||
function resolveLinkTag(reflection, part, externalResolver, useTsResolution) { | ||
let defaultDisplayText = ""; | ||
let pos = 0; | ||
@@ -45,6 +46,13 @@ const end = part.text.length; | ||
} | ||
// Try to parse one | ||
const declRef = (0, declarationReference_1.parseDeclarationReference)(part.text, pos, end); | ||
let target; | ||
let defaultDisplayText = ""; | ||
if (useTsResolution && part.target instanceof models_1.ReflectionSymbolId) { | ||
target = reflection.project.getReflectionFromSymbolId(part.target); | ||
if (target) { | ||
pos = end; | ||
defaultDisplayText = | ||
part.text.replace(/^\s*[A-Z_$][\w$]*[ |]*/i, "") || target.name; | ||
} | ||
} | ||
// Try to parse a declaration reference if we didn't use the TS symbol for resolution | ||
const declRef = !target && (0, declarationReference_1.parseDeclarationReference)(part.text, pos, end); | ||
if (declRef) { | ||
@@ -72,10 +80,7 @@ // Got one, great! Try to resolve the link | ||
} | ||
if (!target) { | ||
if (urlPrefix.test(part.text)) { | ||
const wsIndex = part.text.search(/\s/); | ||
target = | ||
wsIndex === -1 ? part.text : part.text.substring(0, wsIndex); | ||
pos = target.length; | ||
defaultDisplayText = target; | ||
} | ||
if (!target && urlPrefix.test(part.text)) { | ||
const wsIndex = part.text.search(/\s/); | ||
target = wsIndex === -1 ? part.text : part.text.substring(0, wsIndex); | ||
pos = target.length; | ||
defaultDisplayText = target; | ||
} | ||
@@ -82,0 +87,0 @@ // Remaining text after an optional pipe is the link text, so advance |
@@ -302,7 +302,11 @@ "use strict"; | ||
} | ||
block.push({ | ||
const inlineTag = { | ||
kind: "inline-tag", | ||
tag: tagName.text, | ||
text: content.join(""), | ||
}); | ||
}; | ||
if (tagName.linkTarget) { | ||
inlineTag.target = tagName.linkTarget; | ||
} | ||
block.push(inlineTag); | ||
} |
@@ -49,3 +49,3 @@ import ts from "typescript"; | ||
/** @internal */ | ||
get logger(): import("../utils/loggers").Logger; | ||
get logger(): import("../utils").Logger; | ||
/** | ||
@@ -52,0 +52,0 @@ * Return the compiler options. |
@@ -123,6 +123,6 @@ "use strict"; | ||
(index_1.ReflectionKind.SomeModule | index_1.ReflectionKind.Reference)) { | ||
reflection.comment = (0, comments_1.getComment)(exportSymbol, reflection.kind, this.converter.config, this.logger, this.converter.commentStyle); | ||
reflection.comment = (0, comments_1.getComment)(exportSymbol, reflection.kind, this.converter.config, this.logger, this.converter.commentStyle, this.checker); | ||
} | ||
if (symbol && !reflection.comment) { | ||
reflection.comment = (0, comments_1.getComment)(symbol, reflection.kind, this.converter.config, this.logger, this.converter.commentStyle); | ||
reflection.comment = (0, comments_1.getComment)(symbol, reflection.kind, this.converter.config, this.logger, this.converter.commentStyle, this.checker); | ||
} | ||
@@ -129,0 +129,0 @@ if (this.shouldBeStatic) { |
@@ -35,2 +35,4 @@ import ts from "typescript"; | ||
externalSymbolLinkMappings: Record<string, Record<string, string>>; | ||
/** @internal */ | ||
useTsLinkResolution: boolean; | ||
private _config?; | ||
@@ -37,0 +39,0 @@ private _externalSymbolResolvers; |
@@ -126,6 +126,6 @@ "use strict"; | ||
if (comment instanceof index_1.Comment) { | ||
(0, linkResolver_1.resolveLinks)(comment, owner, (ref, part, refl) => this.resolveExternalLink(ref, part, refl)); | ||
(0, linkResolver_1.resolveLinks)(comment, owner, (ref, part, refl) => this.resolveExternalLink(ref, part, refl), this.useTsLinkResolution); | ||
} | ||
else { | ||
return (0, linkResolver_1.resolvePartLinks)(owner, comment, (ref, part, refl) => this.resolveExternalLink(ref, part, refl)); | ||
return (0, linkResolver_1.resolvePartLinks)(owner, comment, (ref, part, refl) => this.resolveExternalLink(ref, part, refl), this.useTsLinkResolution); | ||
} | ||
@@ -170,3 +170,3 @@ } | ||
symbol && | ||
(0, comments_1.getComment)(symbol, context.project.kind, this.config, this.application.logger, this.commentStyle); | ||
(0, comments_1.getComment)(symbol, context.project.kind, this.config, this.application.logger, this.commentStyle, context.checker); | ||
context.trigger(Converter_1.EVENT_CREATE_DECLARATION, context.project); | ||
@@ -339,2 +339,5 @@ moduleContext = context; | ||
], Converter.prototype, "externalSymbolLinkMappings", void 0); | ||
__decorate([ | ||
(0, utils_1.BindOption)("useTsLinkResolution") | ||
], Converter.prototype, "useTsLinkResolution", void 0); | ||
Converter = Converter_1 = __decorate([ | ||
@@ -341,0 +344,0 @@ (0, component_1.Component)({ |
@@ -38,3 +38,3 @@ "use strict"; | ||
models_1.ConversionFlags.VariableOrPropertySource))) { | ||
sigRef.comment = (0, comments_1.getSignatureComment)(declaration, context.converter.config, context.logger, context.converter.commentStyle); | ||
sigRef.comment = (0, comments_1.getSignatureComment)(declaration, context.converter.config, context.logger, context.converter.commentStyle, context.checker); | ||
} | ||
@@ -83,5 +83,5 @@ sigRef.typeParameters = convertTypeParameters(sigRefCtx, sigRef, signature.typeParameters); | ||
if (declaration && typescript_1.default.isJSDocParameterTag(declaration)) { | ||
paramRefl.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger); | ||
paramRefl.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger, context.checker); | ||
} | ||
paramRefl.comment || (paramRefl.comment = (0, comments_1.getComment)(param, paramRefl.kind, context.converter.config, context.logger, context.converter.commentStyle)); | ||
paramRefl.comment || (paramRefl.comment = (0, comments_1.getComment)(param, paramRefl.kind, context.converter.config, context.logger, context.converter.commentStyle, context.checker)); | ||
context.registerReflection(paramRefl, param); | ||
@@ -130,3 +130,3 @@ context.trigger(converter_events_1.ConverterEvents.CREATE_PARAMETER, paramRefl); | ||
if (typescript_1.default.isJSDocParameterTag(param)) { | ||
paramRefl.comment = (0, comments_1.getJsDocComment)(param, context.converter.config, context.logger); | ||
paramRefl.comment = (0, comments_1.getJsDocComment)(param, context.converter.config, context.logger, context.checker); | ||
} | ||
@@ -158,4 +158,6 @@ context.registerReflection(paramRefl, context.getSymbolAtLocation(param)); | ||
// so unfortunately we have to go back to the node for this... | ||
const variance = getVariance(param.getSymbol()?.declarations?.find(typescript_1.default.isTypeParameterDeclaration) | ||
?.modifiers); | ||
const declaration = param | ||
.getSymbol() | ||
?.declarations?.find(typescript_1.default.isTypeParameterDeclaration); | ||
const variance = getVariance(declaration?.modifiers); | ||
const paramRefl = new models_1.TypeParameterReflection(param.symbol.name, parent, variance); | ||
@@ -169,2 +171,6 @@ const paramCtx = context.withScope(paramRefl); | ||
: void 0; | ||
// No way to determine this from the type parameter itself, need to go back to the declaration | ||
if (declaration?.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.ConstKeyword)) { | ||
paramRefl.flags.setFlag(models_1.ReflectionFlag.Const, true); | ||
} | ||
context.registerReflection(paramRefl, param.getSymbol()); | ||
@@ -188,5 +194,8 @@ context.trigger(converter_events_1.ConverterEvents.CREATE_TYPE_PARAMETER, paramRefl); | ||
: void 0; | ||
if (param.modifiers?.some((m) => m.kind === typescript_1.default.SyntaxKind.ConstKeyword)) { | ||
paramRefl.flags.setFlag(models_1.ReflectionFlag.Const, true); | ||
} | ||
context.registerReflection(paramRefl, param.symbol); | ||
if (typescript_1.default.isJSDocTemplateTag(param.parent)) { | ||
paramRefl.comment = (0, comments_1.getJsDocComment)(param.parent, context.converter.config, context.logger); | ||
paramRefl.comment = (0, comments_1.getJsDocComment)(param.parent, context.converter.config, context.logger, context.checker); | ||
} | ||
@@ -193,0 +202,0 @@ context.trigger(converter_events_1.ConverterEvents.CREATE_TYPE_PARAMETER, paramRefl, param); |
@@ -32,3 +32,3 @@ "use strict"; | ||
const reflection = context.createDeclarationReflection(models_1.ReflectionKind.TypeAlias, symbol, exportSymbol); | ||
reflection.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger); | ||
reflection.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger, context.checker); | ||
reflection.type = context.converter.convertType(context.withScope(reflection), declaration.typeExpression?.type); | ||
@@ -41,3 +41,3 @@ convertTemplateParameters(context.withScope(reflection), declaration.parent); | ||
const alias = context.createDeclarationReflection(models_1.ReflectionKind.TypeAlias, symbol, exportSymbol); | ||
alias.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger); | ||
alias.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger, context.checker); | ||
context.finalizeDeclarationReflection(alias); | ||
@@ -51,3 +51,3 @@ const ac = context.withScope(alias); | ||
const reflection = context.createDeclarationReflection(models_1.ReflectionKind.Interface, symbol, exportSymbol); | ||
reflection.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger); | ||
reflection.comment = (0, comments_1.getJsDocComment)(declaration, context.converter.config, context.logger, context.checker); | ||
context.finalizeDeclarationReflection(reflection); | ||
@@ -54,0 +54,0 @@ const rc = context.withScope(reflection); |
@@ -69,3 +69,4 @@ "use strict"; | ||
.indexOf(reflection); | ||
sourceRefl = sourceRefl.getAllSignatures()[index]; | ||
sourceRefl = | ||
sourceRefl.getAllSignatures()[index] || sourceRefl; | ||
} | ||
@@ -72,0 +73,0 @@ } |
@@ -245,4 +245,4 @@ "use strict"; | ||
// or less signatures than declarations. | ||
for (let i = 0; i < signatures.length; i++) { | ||
(0, signature_1.createSignature)(scope, models_1.ReflectionKind.CallSignature, signatures[i], symbol, declarations[i]); | ||
for (const sig of signatures) { | ||
(0, signature_1.createSignature)(scope, models_1.ReflectionKind.CallSignature, sig, symbol); | ||
} | ||
@@ -357,4 +357,6 @@ } | ||
typescript_1.default.isParameter(declaration) || | ||
typescript_1.default.isPropertyAccessExpression(declaration))) { | ||
if (!typescript_1.default.isPropertyAccessExpression(declaration)) { | ||
typescript_1.default.isPropertyAccessExpression(declaration) || | ||
typescript_1.default.isPropertyAssignment(declaration))) { | ||
if (!typescript_1.default.isPropertyAccessExpression(declaration) && | ||
!typescript_1.default.isPropertyAssignment(declaration)) { | ||
parameterType = declaration.type; | ||
@@ -548,3 +550,3 @@ } | ||
reflection.setFlag(models_1.ReflectionFlag.Optional, (0, enum_1.hasAllFlags)(symbol.flags, typescript_1.default.SymbolFlags.Optional)); | ||
reflection.setFlag(models_1.ReflectionFlag.Readonly, (0, enum_1.hasAllFlags)(symbol.checkFlags ?? 0, typescript_1.default.CheckFlags.Readonly) || | ||
reflection.setFlag(models_1.ReflectionFlag.Readonly, (0, enum_1.hasAllFlags)(typescript_1.default.getCheckFlags(symbol), typescript_1.default.CheckFlags.Readonly) || | ||
(0, enum_1.hasAllFlags)(modifiers, typescript_1.default.ModifierFlags.Readonly)); | ||
@@ -551,0 +553,0 @@ reflection.setFlag(models_1.ReflectionFlag.Abstract, (0, enum_1.hasAllFlags)(modifiers, typescript_1.default.ModifierFlags.Abstract)); |
@@ -1,2 +0,2 @@ | ||
import type { Reflection } from "../reflections"; | ||
import type { Reflection, ReflectionSymbolId } from "../reflections"; | ||
import type { Serializer, Deserializer, JSONOutput } from "../../serialization"; | ||
@@ -18,3 +18,3 @@ export type CommentDisplayPart = { | ||
text: string; | ||
target?: Reflection | string; | ||
target?: Reflection | string | ReflectionSymbolId; | ||
} | ||
@@ -45,3 +45,3 @@ /** | ||
clone(): CommentTag; | ||
toObject(): JSONOutput.CommentTag; | ||
toObject(serializer: Serializer): JSONOutput.CommentTag; | ||
fromObject(de: Deserializer, obj: JSONOutput.CommentTag): void; | ||
@@ -80,7 +80,7 @@ } | ||
text: string; | ||
target?: string | Reflection | undefined; | ||
target?: string | Reflection | ReflectionSymbolId | undefined; | ||
})[]; | ||
static serializeDisplayParts(parts: CommentDisplayPart[]): JSONOutput.CommentDisplayPart[]; | ||
static serializeDisplayParts(serializer: Serializer, parts: CommentDisplayPart[]): JSONOutput.CommentDisplayPart[]; | ||
/** @hidden no point in showing this signature in api docs */ | ||
static serializeDisplayParts(parts: CommentDisplayPart[] | undefined): JSONOutput.CommentDisplayPart[] | undefined; | ||
static serializeDisplayParts(serializer: Serializer, parts: CommentDisplayPart[] | undefined): JSONOutput.CommentDisplayPart[] | undefined; | ||
static deserializeDisplayParts(de: Deserializer, parts: JSONOutput.CommentDisplayPart[]): CommentDisplayPart[]; | ||
@@ -87,0 +87,0 @@ /** |
@@ -25,7 +25,7 @@ "use strict"; | ||
} | ||
toObject() { | ||
toObject(serializer) { | ||
return { | ||
tag: this.tag, | ||
name: this.name, | ||
content: Comment.serializeDisplayParts(this.content), | ||
content: Comment.serializeDisplayParts(serializer, this.content), | ||
}; | ||
@@ -90,5 +90,11 @@ } | ||
if (part.target) { | ||
const url = typeof part.target === "string" | ||
? part.target | ||
: urlTo(part.target); | ||
let url; | ||
if (typeof part.target === "string") { | ||
url = part.target; | ||
} | ||
else if (part.target && "id" in part.target) { | ||
// No point in trying to resolve a ReflectionSymbolId at this point, we've already | ||
// tried and failed during the resolution step. | ||
url = urlTo(part.target); | ||
} | ||
const text = part.tag === "@linkcode" | ||
@@ -125,3 +131,3 @@ ? `<code>${part.text}</code>` | ||
} | ||
static serializeDisplayParts(parts) { | ||
static serializeDisplayParts(serializer, parts) { | ||
return parts?.map((part) => { | ||
@@ -133,7 +139,17 @@ switch (part.kind) { | ||
case "inline-tag": { | ||
let target; | ||
if (typeof part.target === "string") { | ||
target = part.target; | ||
} | ||
else if (part.target) { | ||
if ("id" in part.target) { | ||
target = part.target.id; | ||
} | ||
else { | ||
target = part.target.toObject(serializer); | ||
} | ||
} | ||
return { | ||
...part, | ||
target: typeof part.target === "object" | ||
? part.target.id | ||
: part.target, | ||
target, | ||
}; | ||
@@ -260,3 +276,3 @@ } | ||
return { | ||
summary: Comment.serializeDisplayParts(this.summary), | ||
summary: Comment.serializeDisplayParts(serializer, this.summary), | ||
blockTags: serializer.toObjectsOptional(this.blockTags), | ||
@@ -263,0 +279,0 @@ modifierTags: this.modifierTags.size > 0 |
@@ -173,3 +173,2 @@ "use strict"; | ||
} | ||
exports.ReflectionFlags = ReflectionFlags; | ||
ReflectionFlags.serializedFlags = [ | ||
@@ -188,2 +187,3 @@ "isPrivate", | ||
]; | ||
exports.ReflectionFlags = ReflectionFlags; | ||
var TraverseProperty; | ||
@@ -190,0 +190,0 @@ (function (TraverseProperty) { |
@@ -206,3 +206,3 @@ "use strict"; | ||
packageVersion: this.packageVersion, | ||
readme: comments_1.Comment.serializeDisplayParts(this.readme), | ||
readme: comments_1.Comment.serializeDisplayParts(serializer, this.readme), | ||
symbolIdMap, | ||
@@ -209,0 +209,0 @@ }; |
@@ -59,3 +59,2 @@ "use strict"; | ||
} | ||
exports.RendererEvent = RendererEvent; | ||
/** | ||
@@ -71,2 +70,3 @@ * Triggered before the renderer starts rendering a project. | ||
RendererEvent.END = "endRender"; | ||
exports.RendererEvent = RendererEvent; | ||
/** | ||
@@ -81,3 +81,2 @@ * An event emitted by the {@link Renderer} class before and after the | ||
} | ||
exports.PageEvent = PageEvent; | ||
/** | ||
@@ -93,2 +92,3 @@ * Triggered before a document will be rendered. | ||
PageEvent.END = "endPage"; | ||
exports.PageEvent = PageEvent; | ||
/** | ||
@@ -106,3 +106,2 @@ * An event emitted when markdown is being parsed. Allows other plugins to manipulate the result. | ||
} | ||
exports.MarkdownEvent = MarkdownEvent; | ||
/** | ||
@@ -113,2 +112,3 @@ * Triggered on the renderer when this plugin parses a markdown string. | ||
MarkdownEvent.PARSE = "parseMarkdown"; | ||
exports.MarkdownEvent = MarkdownEvent; | ||
/** | ||
@@ -145,3 +145,2 @@ * An event emitted when the search index is being prepared. | ||
} | ||
exports.IndexEvent = IndexEvent; | ||
/** | ||
@@ -152,1 +151,2 @@ * Triggered on the renderer when the search index is being prepared. | ||
IndexEvent.PREPARE_INDEX = "prepareIndex"; | ||
exports.IndexEvent = IndexEvent; |
@@ -92,2 +92,8 @@ "use strict"; | ||
} | ||
else if (project.children?.every((child) => child.kindOf(models_1.ReflectionKind.Module))) { | ||
// If there are no non-module children, then there's no point in having a modules page since there | ||
// will be nothing on it besides the navigation, so redirect the module page to the readme page | ||
project.url = "index.html"; | ||
urls.push(new UrlMapping_1.UrlMapping("index.html", project, this.indexTemplate)); | ||
} | ||
else { | ||
@@ -186,6 +192,6 @@ project.url = "modules.html"; | ||
} | ||
DefaultTheme.URL_PREFIX = /^(http|ftp)s?:\/\//; | ||
exports.DefaultTheme = DefaultTheme; | ||
DefaultTheme.URL_PREFIX = /^(http|ftp)s?:\/\//; | ||
function hasReadme(readme) { | ||
return !readme.endsWith("none"); | ||
} |
@@ -11,2 +11,3 @@ "use strict"; | ||
utils_1.JSX.createElement("h4", null, | ||
item.flags.isConst && "const ", | ||
item.varianceModifier ? `${item.varianceModifier} ` : "", | ||
@@ -13,0 +14,0 @@ item.name, |
@@ -9,4 +9,5 @@ "use strict"; | ||
if ([models_1.ReflectionKind.TypeAlias, models_1.ReflectionKind.Variable].includes(props.model.kind) && | ||
props.model instanceof models_1.DeclarationReflection) | ||
props.model instanceof models_1.DeclarationReflection) { | ||
return context.memberDeclaration(props.model); | ||
} | ||
return (utils_1.JSX.createElement(utils_1.JSX.Fragment, null, | ||
@@ -13,0 +14,0 @@ props.model.hasComment() && (utils_1.JSX.createElement("section", { class: "tsd-panel tsd-comment" }, context.comment(props.model))), |
@@ -84,2 +84,3 @@ "use strict"; | ||
join(utils_1.JSX.createElement("span", { class: "tsd-signature-symbol" }, ", "), typeParameters, (item) => (utils_1.JSX.createElement(utils_1.JSX.Fragment, null, | ||
item.flags.isConst && "const ", | ||
item.varianceModifier ? `${item.varianceModifier} ` : "", | ||
@@ -86,0 +87,0 @@ utils_1.JSX.createElement("span", { class: "tsd-signature-type", "data-tsd-kind": models_1.ReflectionKind.singularString(item.kind) }, item.name)))), |
@@ -169,6 +169,2 @@ /** | ||
} | ||
/** | ||
* If `target` is a number, it is a reflection ID. If a string, it is a URL. | ||
* `target` will only be set for `@link`, `@linkcode`, and `@linkplain` tags. | ||
*/ | ||
export type CommentDisplayPart = { | ||
@@ -180,10 +176,15 @@ kind: "text"; | ||
text: string; | ||
} | { | ||
} | InlineTagDisplayPart; | ||
/** | ||
* If `target` is a number, it is a reflection ID. If a string, it is a URL. | ||
* `target` will only be set for `@link`, `@linkcode`, and `@linkplain` tags. | ||
*/ | ||
export interface InlineTagDisplayPart { | ||
kind: "inline-tag"; | ||
tag: `@${string}`; | ||
text: string; | ||
target?: string | number; | ||
}; | ||
target?: string | number | ReflectionSymbolId; | ||
} | ||
export interface SourceReference extends S<M.SourceReference, "fileName" | "line" | "character" | "url"> { | ||
} | ||
export {}; |
@@ -44,3 +44,2 @@ "use strict"; | ||
} | ||
exports.Serializer = Serializer; | ||
/** | ||
@@ -56,1 +55,2 @@ * Triggered when the {@link Serializer} begins transforming a project. | ||
Serializer.EVENT_END = "end"; | ||
exports.Serializer = Serializer; |
@@ -52,5 +52,5 @@ "use strict"; | ||
} | ||
exports.ComponentEvent = ComponentEvent; | ||
ComponentEvent.ADDED = "componentAdded"; | ||
ComponentEvent.REMOVED = "componentRemoved"; | ||
exports.ComponentEvent = ComponentEvent; | ||
/** | ||
@@ -57,0 +57,0 @@ * Component base class. Has an owner (unless it's the application root component), |
@@ -314,5 +314,5 @@ "use strict"; | ||
} | ||
const packageName = packageJson["name"]; | ||
results.push({ | ||
displayName: typedocPackageConfig?.displayName ?? | ||
packageJson["name"], | ||
displayName: typedocPackageConfig?.displayName ?? packageName, | ||
version: includeVersion | ||
@@ -319,0 +319,0 @@ ? packageJson["version"] |
@@ -102,2 +102,3 @@ import type { Theme as ShikiTheme } from "shiki"; | ||
commentStyle: typeof CommentStyle; | ||
useTsLinkResolution: boolean; | ||
blockTags: `@${string}`[]; | ||
@@ -129,2 +130,3 @@ inlineTags: `@${string}`[]; | ||
treatWarningsAsErrors: boolean; | ||
treatValidationWarningsAsErrors: boolean; | ||
intentionallyNotExported: string[]; | ||
@@ -131,0 +133,0 @@ validation: ValidationOptions; |
@@ -294,3 +294,9 @@ "use strict"; | ||
type: declaration_1.ParameterType.Array, | ||
defaultValue: ["@override", "@virtual", "@privateRemarks"], | ||
defaultValue: [ | ||
"@override", | ||
"@virtual", | ||
"@privateRemarks", | ||
"@satisfies", | ||
"@overload", | ||
], | ||
validate(value) { | ||
@@ -400,2 +406,8 @@ if (!Validation.validate([Array, Validation.isTagString], value)) { | ||
options.addDeclaration({ | ||
name: "useTsLinkResolution", | ||
help: "Use TypeScript's link resolution when determining where @link tags point. This only applies to JSDoc style comments.", | ||
type: declaration_1.ParameterType.Boolean, | ||
defaultValue: true, | ||
}); | ||
options.addDeclaration({ | ||
name: "blockTags", | ||
@@ -587,6 +599,11 @@ help: "Block tags which TypeDoc should recognize when parsing comments.", | ||
name: "treatWarningsAsErrors", | ||
help: "If set, warnings will be treated as errors.", | ||
help: "If set, all warnings will be treated as errors.", | ||
type: declaration_1.ParameterType.Boolean, | ||
}); | ||
options.addDeclaration({ | ||
name: "treatValidationWarningsAsErrors", | ||
help: "If set, warnings emitted during validation will be treated as errors. This option cannot be used to disable treatWarningsAsErrors for validation warnings.", | ||
type: declaration_1.ParameterType.Boolean, | ||
}); | ||
options.addDeclaration({ | ||
name: "intentionallyNotExported", | ||
@@ -593,0 +610,0 @@ help: "A list of types which should not produce 'referenced but not documented' warnings.", |
export declare const tsdocBlockTags: readonly ["@deprecated", "@param", "@remarks", "@returns", "@throws", "@privateRemarks", "@defaultValue", "@typeParam"]; | ||
export declare const blockTags: readonly ["@deprecated", "@param", "@remarks", "@returns", "@throws", "@privateRemarks", "@defaultValue", "@typeParam", "@module", "@inheritDoc", "@group", "@category", "@template", "@type", "@typedef", "@callback", "@prop", "@property"]; | ||
export declare const blockTags: readonly ["@deprecated", "@param", "@remarks", "@returns", "@throws", "@privateRemarks", "@defaultValue", "@typeParam", "@module", "@inheritDoc", "@group", "@category", "@template", "@type", "@typedef", "@callback", "@prop", "@property", "@satisfies"]; | ||
export declare const tsdocInlineTags: readonly ["@link", "@inheritDoc", "@label"]; | ||
export declare const inlineTags: string[]; | ||
export declare const tsdocModifierTags: readonly ["@public", "@private", "@protected", "@internal", "@readonly", "@packageDocumentation", "@eventProperty", "@alpha", "@beta", "@experimental", "@sealed", "@override", "@virtual"]; | ||
export declare const modifierTags: readonly ["@public", "@private", "@protected", "@internal", "@readonly", "@packageDocumentation", "@eventProperty", "@alpha", "@beta", "@experimental", "@sealed", "@override", "@virtual", "@hidden", "@ignore", "@enum", "@event"]; | ||
export declare const modifierTags: readonly ["@public", "@private", "@protected", "@internal", "@readonly", "@packageDocumentation", "@eventProperty", "@alpha", "@beta", "@experimental", "@sealed", "@override", "@virtual", "@hidden", "@ignore", "@enum", "@event", "@overload"]; |
@@ -29,2 +29,3 @@ "use strict"; | ||
"@property", | ||
"@satisfies", | ||
]; | ||
@@ -54,2 +55,3 @@ exports.tsdocInlineTags = ["@link", "@inheritDoc", "@label"]; | ||
"@event", | ||
"@overload", | ||
]; |
@@ -47,9 +47,9 @@ "use strict"; | ||
if (hasOwnProperty(packageJson, "typedoc") && | ||
typeof packageJson.typedoc == "object" && | ||
packageJson.typedoc) { | ||
if (!(0, validation_1.validate)(typedocPackageManifestConfigSchema, packageJson.typedoc)) { | ||
typeof packageJson["typedoc"] == "object" && | ||
packageJson["typedoc"]) { | ||
if (!(0, validation_1.validate)(typedocPackageManifestConfigSchema, packageJson["typedoc"])) { | ||
logger.error(`Typedoc config extracted from package manifest file ${packageJsonPath} is not valid`); | ||
return undefined; | ||
} | ||
return packageJson.typedoc; | ||
return packageJson["typedoc"]; | ||
} | ||
@@ -56,0 +56,0 @@ return undefined; |
{ | ||
"name": "typedoc", | ||
"description": "Create api documentation for TypeScript projects.", | ||
"version": "0.24.0-beta.3", | ||
"version": "0.24.0-beta.4", | ||
"homepage": "https://typedoc.org", | ||
@@ -33,3 +33,3 @@ "exports": { | ||
"peerDependencies": { | ||
"typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x" | ||
"typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x" | ||
}, | ||
@@ -41,8 +41,8 @@ "devDependencies": { | ||
"@types/node": "14", | ||
"@typescript-eslint/eslint-plugin": "^5.51.0", | ||
"@typescript-eslint/parser": "^5.51.0", | ||
"@typescript-eslint/eslint-plugin": "^5.55.0", | ||
"@typescript-eslint/parser": "^5.55.0", | ||
"@typestrong/fs-fixture-builder": "github:TypeStrong/fs-fixture-builder#8abd1494280116ff5318dde2c50ad01e1663790c", | ||
"c8": "^7.12.0", | ||
"esbuild": "^0.17.7", | ||
"eslint": "^8.34.0", | ||
"c8": "^7.13.0", | ||
"esbuild": "^0.17.12", | ||
"eslint": "^8.36.0", | ||
"mocha": "^10.2.0", | ||
@@ -52,3 +52,3 @@ "prettier": "2.8.4", | ||
"ts-node": "^10.9.1", | ||
"typescript": "4.9.5" | ||
"typescript": "5.0.2" | ||
}, | ||
@@ -55,0 +55,0 @@ "files": [ |
@@ -44,3 +44,3 @@ # TypeDoc | ||
requires configuration to be present in each directory to specify the entry points. For an example setup, see | ||
`<TODO need to create example>` | ||
https://github.com/Gerrit0/typedoc-packages-example | ||
@@ -47,0 +47,0 @@ ### Arguments |
@@ -69,4 +69,20 @@ { | ||
"allowMultiple": true | ||
}, | ||
{ | ||
"tagName": "@private", | ||
"syntaxKind": "modifier" | ||
}, | ||
{ | ||
"tagName": "@protected", | ||
"syntaxKind": "modifier" | ||
}, | ||
{ | ||
"tagName": "@satisfies", | ||
"syntaxKind": "block" | ||
}, | ||
{ | ||
"tagName": "@overload", | ||
"syntaxKind": "modifier" | ||
} | ||
] | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1121218
26234