UNPKG

16.8 kBSource Map (JSON)View Raw
1{"version":3,"file":"AstReferenceResolver.js","sourceRoot":"","sources":["../../src/analyzer/AstReferenceResolver.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;AAE3D,+CAAiC;AACjC,wDAA0C;AAS1C,2CAAwC;AAExC;;;;;;;GAOG;AACH,MAAa,eAAe;IAM1B,YAAmB,MAAc;QAC/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AATD,0CASC;AAED;;;;;;;GAOG;AACH,MAAa,oBAAoB;IAK/B,YAAmB,SAAoB;QACrC,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC,cAAc,CAAC;QAChD,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC,cAAc,CAAC;IAClD,CAAC;IAEM,OAAO,CAAC,oBAAmD;QAChE,0CAA0C;QAC1C,IACE,oBAAoB,CAAC,WAAW,KAAK,SAAS;YAC9C,oBAAoB,CAAC,WAAW,KAAK,IAAI,CAAC,eAAe,CAAC,IAAI,EAC9D;YACA,OAAO,IAAI,eAAe,CAAC,+CAA+C,CAAC,CAAC;SAC7E;QAED,6BAA6B;QAC7B,IAAI,oBAAoB,CAAC,UAAU,EAAE;YACnC,OAAO,IAAI,eAAe,CAAC,gCAAgC,CAAC,CAAC;SAC9D;QAED,MAAM,SAAS,GAAc,IAAI,CAAC,eAAe,CAAC,gCAAgC,CAChF,IAAI,CAAC,eAAe,CAAC,oBAAoB,CAC1C,CAAC;QAEF,IAAI,oBAAoB,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE;YACtD,OAAO,IAAI,eAAe,CAAC,sCAAsC,CAAC,CAAC;SACpE;QAED,MAAM,mBAAmB,GAA6B,oBAAoB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;QAE/F,MAAM,UAAU,GAA6B,IAAI,CAAC,6BAA6B,CAAC,mBAAmB,CAAC,CAAC;QACrG,IAAI,UAAU,YAAY,eAAe,EAAE;YACzC,OAAO,UAAU,CAAC;SACnB;QAED,MAAM,aAAa,GAA0B,IAAI,CAAC,eAAe,CAAC,uBAAuB,CACvF,UAAU,EACV,SAAS,CACV,CAAC;QAEF,IAAI,aAAa,KAAK,SAAS,EAAE;YAC/B,OAAO,IAAI,eAAe,CACxB,gBAAgB,IAAI,CAAC,eAAe,CAAC,IAAI,8BAA8B,UAAU,GAAG,CACrF,CAAC;SACH;QAED,IAAI,CAAC,CAAC,aAAa,YAAY,qBAAS,CAAC,EAAE;YACzC,OAAO,IAAI,eAAe,CAAC,+DAA+D,CAAC,CAAC;SAC7F;QAED,IAAI,kBAAkB,GAAqC,IAAI,CAAC,kBAAkB,CAChF,aAAa,CAAC,eAAe,EAC7B,mBAAmB,EACnB,aAAa,CAAC,SAAS,CACxB,CAAC;QAEF,IAAI,kBAAkB,YAAY,eAAe,EAAE;YACjD,OAAO,kBAAkB,CAAC;SAC3B;QAED,KAAK,IAAI,KAAK,GAAW,CAAC,EAAE,KAAK,GAAG,oBAAoB,CAAC,gBAAgB,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE;YACzF,MAAM,eAAe,GAA6B,oBAAoB,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAE/F,MAAM,UAAU,GAA6B,IAAI,CAAC,6BAA6B,CAAC,eAAe,CAAC,CAAC;YACjG,IAAI,UAAU,YAAY,eAAe,EAAE;gBACzC,OAAO,UAAU,CAAC;aACnB;YAED,MAAM,gBAAgB,GACpB,kBAAkB,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;YACtD,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE;gBACjC,OAAO,IAAI,eAAe,CAAC,kCAAkC,UAAU,GAAG,CAAC,CAAC;aAC7E;YAED,MAAM,mBAAmB,GAAqC,IAAI,CAAC,kBAAkB,CACnF,gBAAgB,EAChB,eAAe,EACf,UAAU,CACX,CAAC;YAEF,IAAI,mBAAmB,YAAY,eAAe,EAAE;gBAClD,OAAO,mBAAmB,CAAC;aAC5B;YAED,kBAAkB,GAAG,mBAAmB,CAAC;SAC1C;QAED,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAEO,6BAA6B,CAAC,eAAyC;QAC7E,IAAI,eAAe,CAAC,YAAY,KAAK,SAAS,EAAE;YAC9C,OAAO,IAAI,eAAe,CAAC,+CAA+C,CAAC,CAAC;SAC7E;QACD,IAAI,eAAe,CAAC,gBAAgB,KAAK,SAAS,EAAE;YAClD,OAAO,IAAI,eAAe,CAAC,+DAA+D,CAAC,CAAC;SAC7F;QACD,OAAO,eAAe,CAAC,gBAAgB,CAAC,UAAU,CAAC;IACrD,CAAC;IAEO,kBAAkB,CACxB,eAA8C,EAC9C,eAAyC,EACzC,aAAqB;QAErB,MAAM,cAAc,GAAwC,eAAe,CAAC,QAAQ,CAAC;QAErF,IAAI,cAAc,KAAK,SAAS,EAAE;YAChC,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;gBAChC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC;aAC3B;iBAAM;gBACL,mFAAmF;gBACnF,oCAAoC;gBACpC,MAAM,iBAAiB,GACrB,IAAI,CAAC,gCAAgC,CAAC,eAAe,CAAC,CAAC;gBACzD,IAAI,iBAAiB,EAAE;oBACrB,OAAO,iBAAiB,CAAC;iBAC1B;gBAED,OAAO,IAAI,eAAe,CACxB,uCAAuC,aAAa,GAAG;oBACrD,mFAAmF,CACtF,CAAC;aACH;SACF;QAED,QAAQ,cAAc,CAAC,YAAY,EAAE;YACnC,KAAK,KAAK,CAAC,YAAY,CAAC,MAAM;gBAC5B,OAAO,IAAI,CAAC,0BAA0B,CAAC,eAAe,EAAE,cAAc,EAAE,aAAa,CAAC,CAAC;YACzF,KAAK,KAAK,CAAC,YAAY,CAAC,KAAK;gBAC3B,OAAO,IAAI,CAAC,yBAAyB,CAAC,eAAe,EAAE,cAAc,EAAE,aAAa,CAAC,CAAC;SACzF;QAED,OAAO,IAAI,eAAe,CAAC,iBAAiB,cAAc,CAAC,QAAQ,oCAAoC,CAAC,CAAC;IAC3G,CAAC;IAEO,0BAA0B,CAChC,eAA8C,EAC9C,cAAuC,EACvC,aAAqB;QAErB,MAAM,YAAY,GAAW,cAAc,CAAC,QAAQ,CAAC;QAErD,IAAI,kBAAiC,CAAC;QAEtC,QAAQ,YAAY,EAAE;YACpB,KAAK,OAAO;gBACV,kBAAkB,GAAG,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC;gBACpD,MAAM;YACR,KAAK,MAAM;gBACT,kBAAkB,GAAG,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC;gBACnD,MAAM;YACR,KAAK,UAAU;gBACb,kBAAkB,GAAG,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC;gBACvD,MAAM;YACR,KAAK,WAAW;gBACd,kBAAkB,GAAG,EAAE,CAAC,UAAU,CAAC,oBAAoB,CAAC;gBACxD,MAAM;YACR,KAAK,WAAW;gBACd,kBAAkB,GAAG,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC;gBACrD,MAAM;YACR,KAAK,MAAM;gBACT,kBAAkB,GAAG,EAAE,CAAC,UAAU,CAAC,oBAAoB,CAAC;gBACxD,MAAM;YACR,KAAK,UAAU;gBACb,kBAAkB,GAAG,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC;gBACvD,MAAM;YACR;gBACE,OAAO,IAAI,eAAe,CAAC,gCAAgC,YAAY,GAAG,CAAC,CAAC;SAC/E;QAED,MAAM,OAAO,GAAqB,eAAe,CAAC,MAAM,CACtD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,KAAK,kBAAkB,CACjD,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;YACxB,OAAO,IAAI,eAAe,CACxB,sBAAsB,aAAa,kCAAkC;gBACnE,oBAAoB,YAAY,GAAG,CACtC,CAAC;SACH;QACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;YACtB,mFAAmF;YACnF,oCAAoC;YACpC,MAAM,iBAAiB,GAA+B,IAAI,CAAC,gCAAgC,CAAC,OAAO,CAAC,CAAC;YACrG,IAAI,iBAAiB,EAAE;gBACrB,OAAO,iBAAiB,CAAC;aAC1B;YAED,OAAO,IAAI,eAAe,CACxB,8BAA8B,aAAa,iCAAiC,YAAY,GAAG,CAC5F,CAAC;SACH;QACD,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAEO,yBAAyB,CAC/B,eAA8C,EAC9C,cAAuC,EACvC,aAAqB;QAErB,MAAM,qBAAqB,GAAW,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAExE,MAAM,OAAO,GAAqB,EAAE,CAAC;QACrC,KAAK,MAAM,cAAc,IAAI,eAAe,EAAE;YAC5C,MAAM,aAAa,GAAW,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;YAC/E,IAAI,aAAa,KAAK,qBAAqB,EAAE;gBAC3C,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;aAC9B;SACF;QAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;YACxB,OAAO,IAAI,eAAe,CACxB,oBAAoB,aAAa,kCAAkC;gBACjE,qBAAqB,qBAAqB,GAAG,CAChD,CAAC;SACH;QACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;YACtB,mFAAmF;YACnF,oCAAoC;YACpC,MAAM,iBAAiB,GAA+B,IAAI,CAAC,gCAAgC,CAAC,OAAO,CAAC,CAAC;YACrG,IAAI,iBAAiB,EAAE;gBACrB,OAAO,iBAAiB,CAAC;aAC1B;YAED,OAAO,IAAI,eAAe,CACxB,kCAAkC,aAAa,eAAe;gBAC5D,qBAAqB,qBAAqB,GAAG,CAChD,CAAC;SACH;QACD,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED;;;OAGG;IACK,gCAAgC,CACtC,OAAsC;QAEtC,IAAI,MAAM,GAA+B,SAAS,CAAC;QAEnD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE;YAC3B,MAAM,mBAAmB,GAAwB,IAAI,CAAC,UAAU,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;YACjG,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE;gBACpC,IAAI,MAAM,EAAE;oBACV,OAAO,SAAS,CAAC,CAAC,sBAAsB;iBACzC;gBACD,MAAM,GAAG,KAAK,CAAC;aAChB;SACF;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAjQD,oDAiQC","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 * as ts from 'typescript';\nimport * as tsdoc from '@microsoft/tsdoc';\n\nimport { AstSymbolTable } from './AstSymbolTable';\nimport { AstEntity } from './AstEntity';\nimport { AstDeclaration } from './AstDeclaration';\nimport { WorkingPackage } from '../collector/WorkingPackage';\nimport { AstModule } from './AstModule';\nimport { Collector } from '../collector/Collector';\nimport { DeclarationMetadata } from '../collector/DeclarationMetadata';\nimport { AstSymbol } from './AstSymbol';\n\n/**\n * Used by `AstReferenceResolver` to report a failed resolution.\n *\n * @privateRemarks\n * This class is similar to an `Error` object, but the intent of `ResolverFailure` is to describe\n * why a reference could not be resolved. This information could be used to throw an actual `Error` object,\n * but normally it is handed off to the `MessageRouter` instead.\n */\nexport class ResolverFailure {\n /**\n * Details about why the failure occurred.\n */\n public readonly reason: string;\n\n public constructor(reason: string) {\n this.reason = reason;\n }\n}\n\n/**\n * This resolves a TSDoc declaration reference by walking the `AstSymbolTable` compiler state.\n *\n * @remarks\n *\n * This class is analogous to `ModelReferenceResolver` from the `@microsoft/api-extractor-model` project,\n * which resolves declaration references by walking the hierarchy loaded from an .api.json file.\n */\nexport class AstReferenceResolver {\n private readonly _collector: Collector;\n private readonly _astSymbolTable: AstSymbolTable;\n private readonly _workingPackage: WorkingPackage;\n\n public constructor(collector: Collector) {\n this._collector = collector;\n this._astSymbolTable = collector.astSymbolTable;\n this._workingPackage = collector.workingPackage;\n }\n\n public resolve(declarationReference: tsdoc.DocDeclarationReference): AstDeclaration | ResolverFailure {\n // Is it referring to the working package?\n if (\n declarationReference.packageName !== undefined &&\n declarationReference.packageName !== this._workingPackage.name\n ) {\n return new ResolverFailure('External package references are not supported');\n }\n\n // Is it a path-based import?\n if (declarationReference.importPath) {\n return new ResolverFailure('Import paths are not supported');\n }\n\n const astModule: AstModule = this._astSymbolTable.fetchAstModuleFromWorkingPackage(\n this._workingPackage.entryPointSourceFile\n );\n\n if (declarationReference.memberReferences.length === 0) {\n return new ResolverFailure('Package references are not supported');\n }\n\n const rootMemberReference: tsdoc.DocMemberReference = declarationReference.memberReferences[0];\n\n const exportName: string | ResolverFailure = this._getMemberReferenceIdentifier(rootMemberReference);\n if (exportName instanceof ResolverFailure) {\n return exportName;\n }\n\n const rootAstEntity: AstEntity | undefined = this._astSymbolTable.tryGetExportOfAstModule(\n exportName,\n astModule\n );\n\n if (rootAstEntity === undefined) {\n return new ResolverFailure(\n `The package \"${this._workingPackage.name}\" does not have an export \"${exportName}\"`\n );\n }\n\n if (!(rootAstEntity instanceof AstSymbol)) {\n return new ResolverFailure('This type of declaration is not supported yet by the resolver');\n }\n\n let currentDeclaration: AstDeclaration | ResolverFailure = this._selectDeclaration(\n rootAstEntity.astDeclarations,\n rootMemberReference,\n rootAstEntity.localName\n );\n\n if (currentDeclaration instanceof ResolverFailure) {\n return currentDeclaration;\n }\n\n for (let index: number = 1; index < declarationReference.memberReferences.length; ++index) {\n const memberReference: tsdoc.DocMemberReference = declarationReference.memberReferences[index];\n\n const memberName: string | ResolverFailure = this._getMemberReferenceIdentifier(memberReference);\n if (memberName instanceof ResolverFailure) {\n return memberName;\n }\n\n const matchingChildren: ReadonlyArray<AstDeclaration> =\n currentDeclaration.findChildrenWithName(memberName);\n if (matchingChildren.length === 0) {\n return new ResolverFailure(`No member was found with name \"${memberName}\"`);\n }\n\n const selectedDeclaration: AstDeclaration | ResolverFailure = this._selectDeclaration(\n matchingChildren,\n memberReference,\n memberName\n );\n\n if (selectedDeclaration instanceof ResolverFailure) {\n return selectedDeclaration;\n }\n\n currentDeclaration = selectedDeclaration;\n }\n\n return currentDeclaration;\n }\n\n private _getMemberReferenceIdentifier(memberReference: tsdoc.DocMemberReference): string | ResolverFailure {\n if (memberReference.memberSymbol !== undefined) {\n return new ResolverFailure('ECMAScript symbol selectors are not supported');\n }\n if (memberReference.memberIdentifier === undefined) {\n return new ResolverFailure('The member identifier is missing in the root member reference');\n }\n return memberReference.memberIdentifier.identifier;\n }\n\n private _selectDeclaration(\n astDeclarations: ReadonlyArray<AstDeclaration>,\n memberReference: tsdoc.DocMemberReference,\n astSymbolName: string\n ): AstDeclaration | ResolverFailure {\n const memberSelector: tsdoc.DocMemberSelector | undefined = memberReference.selector;\n\n if (memberSelector === undefined) {\n if (astDeclarations.length === 1) {\n return astDeclarations[0];\n } else {\n // If we found multiple matches, but the extra ones are all ancillary declarations,\n // then return the main declaration.\n const nonAncillaryMatch: AstDeclaration | undefined =\n this._tryDisambiguateAncillaryMatches(astDeclarations);\n if (nonAncillaryMatch) {\n return nonAncillaryMatch;\n }\n\n return new ResolverFailure(\n `The reference is ambiguous because \"${astSymbolName}\"` +\n ` has more than one declaration; you need to add a TSDoc member reference selector`\n );\n }\n }\n\n switch (memberSelector.selectorKind) {\n case tsdoc.SelectorKind.System:\n return this._selectUsingSystemSelector(astDeclarations, memberSelector, astSymbolName);\n case tsdoc.SelectorKind.Index:\n return this._selectUsingIndexSelector(astDeclarations, memberSelector, astSymbolName);\n }\n\n return new ResolverFailure(`The selector \"${memberSelector.selector}\" is not a supported selector type`);\n }\n\n private _selectUsingSystemSelector(\n astDeclarations: ReadonlyArray<AstDeclaration>,\n memberSelector: tsdoc.DocMemberSelector,\n astSymbolName: string\n ): AstDeclaration | ResolverFailure {\n const selectorName: string = memberSelector.selector;\n\n let selectorSyntaxKind: ts.SyntaxKind;\n\n switch (selectorName) {\n case 'class':\n selectorSyntaxKind = ts.SyntaxKind.ClassDeclaration;\n break;\n case 'enum':\n selectorSyntaxKind = ts.SyntaxKind.EnumDeclaration;\n break;\n case 'function':\n selectorSyntaxKind = ts.SyntaxKind.FunctionDeclaration;\n break;\n case 'interface':\n selectorSyntaxKind = ts.SyntaxKind.InterfaceDeclaration;\n break;\n case 'namespace':\n selectorSyntaxKind = ts.SyntaxKind.ModuleDeclaration;\n break;\n case 'type':\n selectorSyntaxKind = ts.SyntaxKind.TypeAliasDeclaration;\n break;\n case 'variable':\n selectorSyntaxKind = ts.SyntaxKind.VariableDeclaration;\n break;\n default:\n return new ResolverFailure(`Unsupported system selector \"${selectorName}\"`);\n }\n\n const matches: AstDeclaration[] = astDeclarations.filter(\n (x) => x.declaration.kind === selectorSyntaxKind\n );\n if (matches.length === 0) {\n return new ResolverFailure(\n `A declaration for \"${astSymbolName}\" was not found that matches the` +\n ` TSDoc selector \"${selectorName}\"`\n );\n }\n if (matches.length > 1) {\n // If we found multiple matches, but the extra ones are all ancillary declarations,\n // then return the main declaration.\n const nonAncillaryMatch: AstDeclaration | undefined = this._tryDisambiguateAncillaryMatches(matches);\n if (nonAncillaryMatch) {\n return nonAncillaryMatch;\n }\n\n return new ResolverFailure(\n `More than one declaration \"${astSymbolName}\" matches the TSDoc selector \"${selectorName}\"`\n );\n }\n return matches[0];\n }\n\n private _selectUsingIndexSelector(\n astDeclarations: ReadonlyArray<AstDeclaration>,\n memberSelector: tsdoc.DocMemberSelector,\n astSymbolName: string\n ): AstDeclaration | ResolverFailure {\n const selectorOverloadIndex: number = parseInt(memberSelector.selector);\n\n const matches: AstDeclaration[] = [];\n for (const astDeclaration of astDeclarations) {\n const overloadIndex: number = this._collector.getOverloadIndex(astDeclaration);\n if (overloadIndex === selectorOverloadIndex) {\n matches.push(astDeclaration);\n }\n }\n\n if (matches.length === 0) {\n return new ResolverFailure(\n `An overload for \"${astSymbolName}\" was not found that matches the` +\n ` TSDoc selector \":${selectorOverloadIndex}\"`\n );\n }\n if (matches.length > 1) {\n // If we found multiple matches, but the extra ones are all ancillary declarations,\n // then return the main declaration.\n const nonAncillaryMatch: AstDeclaration | undefined = this._tryDisambiguateAncillaryMatches(matches);\n if (nonAncillaryMatch) {\n return nonAncillaryMatch;\n }\n\n return new ResolverFailure(\n `More than one declaration for \"${astSymbolName}\" matches the` +\n ` TSDoc selector \":${selectorOverloadIndex}\"`\n );\n }\n return matches[0];\n }\n\n /**\n * This resolves an ambiguous match in the case where the extra matches are all ancillary declarations,\n * except for one match that is the main declaration.\n */\n private _tryDisambiguateAncillaryMatches(\n matches: ReadonlyArray<AstDeclaration>\n ): AstDeclaration | undefined {\n let result: AstDeclaration | undefined = undefined;\n\n for (const match of matches) {\n const declarationMetadata: DeclarationMetadata = this._collector.fetchDeclarationMetadata(match);\n if (!declarationMetadata.isAncillary) {\n if (result) {\n return undefined; // more than one match\n }\n result = match;\n }\n }\n return result;\n }\n}\n"]}
\No newline at end of file