Commit 956c501c authored by DatHV's avatar DatHV
Browse files

update build x-app-sdk

parent 9bb8aadd
{"version":3,"file":"AstSymbolTable.d.ts","sourceRoot":"","sources":["../../src/analyzer/AstSymbolTable.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,EAAE,KAAK,iBAAiB,EAAiB,MAAM,8BAA8B,CAAC;AAErF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAKhE;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,cAAc,EAAE,EAAE,CAAC,MAAM,CAAC;IAC1B;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAEhC;;;OAGG;IACH,YAAY,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiB;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAA0B;IAClE,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAyB;IACjE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAc;IAExD;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA8D;IAElG;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,6BAA6B,CAG1C;IAIJ,OAAO,CAAC,QAAQ,CAAC,eAAe,CAG5B;gBAGF,OAAO,EAAE,EAAE,CAAC,OAAO,EACnB,WAAW,EAAE,EAAE,CAAC,WAAW,EAC3B,iBAAiB,EAAE,iBAAiB,EACpC,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,EACxC,aAAa,EAAE,aAAa;IAgB9B;;OAEG;IACI,gCAAgC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,SAAS;IAI7E;;OAEG;IACI,wBAAwB,CAAC,SAAS,EAAE,SAAS,GAAG,oBAAoB;IAI3E;;;OAGG;IACI,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS;IAI/F;;;;;;;;;;;;OAYG;IACI,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAU1C;;;;OAIG;IAEI,4BAA4B,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,oBAAoB,EAAE,cAAc,GAAG,cAAc;IAgBxG;;;;;OAKG;IACI,mBAAmB,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,cAAc,GAAG,SAAS,GAAG,SAAS;IAOhG;;;;;;;;;;;;;;OAcG;WACW,qBAAqB,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,GAAG,MAAM;IAmE9D,OAAO,CAAC,0BAA0B;IAiBlC,OAAO,CAAC,iBAAiB;IA4CzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAsIzB,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,oBAAoB;IAiC5B,OAAO,CAAC,eAAe;IA2JvB;;OAEG;IACH,OAAO,CAAC,iCAAiC;CAU1C"}
\ No newline at end of file
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.AstSymbolTable = void 0;
/* eslint-disable no-bitwise */ // for ts.SymbolFlags
const ts = __importStar(require("typescript"));
const node_core_library_1 = require("@rushstack/node-core-library");
const AstDeclaration_1 = require("./AstDeclaration");
const TypeScriptHelpers_1 = require("./TypeScriptHelpers");
const AstSymbol_1 = require("./AstSymbol");
const PackageMetadataManager_1 = require("./PackageMetadataManager");
const ExportAnalyzer_1 = require("./ExportAnalyzer");
const AstNamespaceImport_1 = require("./AstNamespaceImport");
const TypeScriptInternals_1 = require("./TypeScriptInternals");
const SyntaxHelpers_1 = require("./SyntaxHelpers");
const SourceFileLocationFormatter_1 = require("./SourceFileLocationFormatter");
/**
* AstSymbolTable is the workhorse that builds AstSymbol and AstDeclaration objects.
* It maintains a cache of already constructed objects. AstSymbolTable constructs
* AstModule objects, but otherwise the state that it maintains is agnostic of
* any particular entry point. (For example, it does not track whether a given AstSymbol
* is "exported" or not.)
*
* Internally, AstSymbolTable relies on ExportAnalyzer to crawl import statements and determine where symbols
* are declared (i.e. the AstImport information needed to import them).
*/
class AstSymbolTable {
constructor(program, typeChecker, packageJsonLookup, bundledPackageNames, messageRouter) {
/**
* A mapping from ts.Symbol --> AstSymbol
* NOTE: The AstSymbol.followedSymbol will always be a lookup key, but additional keys
* are possible.
*
* After following type aliases, we use this map to look up the corresponding AstSymbol.
*/
this._astSymbolsBySymbol = new Map();
/**
* A mapping from ts.Declaration --> AstDeclaration
*/
this._astDeclarationsByDeclaration = new Map();
// Note that this is a mapping from specific AST nodes that we analyzed, based on the underlying symbol
// for that node.
this._entitiesByNode = new Map();
this._program = program;
this._typeChecker = typeChecker;
this._messageRouter = messageRouter;
this._globalVariableAnalyzer = TypeScriptInternals_1.TypeScriptInternals.getGlobalVariableAnalyzer(program);
this._packageMetadataManager = new PackageMetadataManager_1.PackageMetadataManager(packageJsonLookup, messageRouter);
this._exportAnalyzer = new ExportAnalyzer_1.ExportAnalyzer(this._program, this._typeChecker, bundledPackageNames, {
analyze: this.analyze.bind(this),
fetchAstSymbol: this._fetchAstSymbol.bind(this)
});
this._alreadyWarnedGlobalNames = new Set();
}
/**
* Used to analyze an entry point that belongs to the working package.
*/
fetchAstModuleFromWorkingPackage(sourceFile) {
return this._exportAnalyzer.fetchAstModuleFromSourceFile(sourceFile, undefined, false);
}
/**
* This crawls the specified entry point and collects the full set of exported AstSymbols.
*/
fetchAstModuleExportInfo(astModule) {
return this._exportAnalyzer.fetchAstModuleExportInfo(astModule);
}
/**
* Attempts to retrieve an export by name from the specified `AstModule`.
* Returns undefined if no match was found.
*/
tryGetExportOfAstModule(exportName, astModule) {
return this._exportAnalyzer.tryGetExportOfAstModule(exportName, astModule);
}
/**
* Ensures that AstSymbol.analyzed is true for the provided symbol. The operation
* starts from the root symbol and then fills out all children of all declarations, and
* also calculates AstDeclaration.referencedAstSymbols for all declarations.
* If the symbol is not imported, any non-imported references are also analyzed.
*
* @remarks
* This is an expensive operation, so we only perform it for top-level exports of an
* the AstModule. For example, if some code references a nested class inside
* a namespace from another library, we do not analyze any of that class's siblings
* or members. (We do always construct its parents however, since AstDefinition.parent
* is immutable, and needed e.g. to calculate release tag inheritance.)
*/
analyze(astEntity) {
if (astEntity instanceof AstSymbol_1.AstSymbol) {
return this._analyzeAstSymbol(astEntity);
}
if (astEntity instanceof AstNamespaceImport_1.AstNamespaceImport) {
return this._analyzeAstNamespaceImport(astEntity);
}
}
/**
* For a given astDeclaration, this efficiently finds the child corresponding to the
* specified ts.Node. It is assumed that AstDeclaration.isSupportedSyntaxKind() would return true for
* that node type, and that the node is an immediate child of the provided AstDeclaration.
*/
// NOTE: This could be a method of AstSymbol if it had a backpointer to its AstSymbolTable.
getChildAstDeclarationByNode(node, parentAstDeclaration) {
if (!parentAstDeclaration.astSymbol.analyzed) {
throw new Error('getChildDeclarationByNode() cannot be used for an AstSymbol that was not analyzed');
}
const childAstDeclaration = this._astDeclarationsByDeclaration.get(node);
if (!childAstDeclaration) {
throw new Error('Child declaration not found for the specified node');
}
if (childAstDeclaration.parent !== parentAstDeclaration) {
throw new node_core_library_1.InternalError('The found child is not attached to the parent AstDeclaration');
}
return childAstDeclaration;
}
/**
* For a given ts.Identifier that is part of an AstSymbol that we analyzed, return the AstEntity that
* it refers to. Returns undefined if it doesn't refer to anything interesting.
* @remarks
* Throws an Error if the ts.Identifier is not part of node tree that was analyzed.
*/
tryGetEntityForNode(identifier) {
if (!this._entitiesByNode.has(identifier)) {
throw new node_core_library_1.InternalError('tryGetEntityForIdentifier() called for an identifier that was not analyzed');
}
return this._entitiesByNode.get(identifier);
}
/**
* Builds an AstSymbol.localName for a given ts.Symbol. In the current implementation, the localName is
* a TypeScript-like expression that may be a string literal or ECMAScript symbol expression.
*
* ```ts
* class X {
* // localName="identifier"
* public identifier: number = 1;
* // localName="\"identifier\""
* public "quoted string!": number = 2;
* // localName="[MyNamespace.MySymbol]"
* public [MyNamespace.MySymbol]: number = 3;
* }
* ```
*/
static getLocalNameForSymbol(symbol) {
// TypeScript binds well-known ECMAScript symbols like "[Symbol.iterator]" as "__@iterator".
// Decode it back into "[Symbol.iterator]".
const wellKnownSymbolName = TypeScriptHelpers_1.TypeScriptHelpers.tryDecodeWellKnownSymbolName(symbol.escapedName);
if (wellKnownSymbolName) {
return wellKnownSymbolName;
}
const isUniqueSymbol = TypeScriptHelpers_1.TypeScriptHelpers.isUniqueSymbolName(symbol.escapedName);
// We will try to obtain the name from a declaration; otherwise we'll fall back to the symbol name.
let unquotedName = symbol.name;
for (const declaration of symbol.declarations || []) {
// Handle cases such as "export default class X { }" where the symbol name is "default"
// but the local name is "X".
const localSymbol = TypeScriptInternals_1.TypeScriptInternals.tryGetLocalSymbol(declaration);
if (localSymbol) {
unquotedName = localSymbol.name;
}
// If it is a non-well-known symbol, then return the late-bound name. For example, "X.Y.z" in this example:
//
// namespace X {
// export namespace Y {
// export const z: unique symbol = Symbol("z");
// }
// }
//
// class C {
// public [X.Y.z](): void { }
// }
//
if (isUniqueSymbol) {
const declarationName = ts.getNameOfDeclaration(declaration);
if (declarationName && ts.isComputedPropertyName(declarationName)) {
const lateBoundName = TypeScriptHelpers_1.TypeScriptHelpers.tryGetLateBoundName(declarationName);
if (lateBoundName) {
// Here the string may contain an expression such as "[X.Y.z]". Names starting with "[" are always
// expressions. If a string literal contains those characters, the code below will JSON.stringify() it
// to avoid a collision.
return lateBoundName;
}
}
}
}
// Otherwise that name may come from a quoted string or pseudonym like `__constructor`.
// If the string is not a safe identifier, then we must add quotes.
// Note that if it was quoted but did not need to be quoted, here we will remove the quotes.
if (!SyntaxHelpers_1.SyntaxHelpers.isSafeUnquotedMemberIdentifier(unquotedName)) {
// For API Extractor's purposes, a canonical form is more appropriate than trying to reflect whatever
// appeared in the source code. The code is not even guaranteed to be consistent, for example:
//
// class X {
// public "f1"(x: string): void;
// public f1(x: boolean): void;
// public 'f1'(x: string | boolean): void { }
// }
return JSON.stringify(unquotedName);
}
return unquotedName;
}
_analyzeAstNamespaceImport(astNamespaceImport) {
if (astNamespaceImport.analyzed) {
return;
}
// mark before actual analyzing, to handle module cyclic reexport
astNamespaceImport.analyzed = true;
const exportedLocalEntities = this.fetchAstModuleExportInfo(astNamespaceImport.astModule).exportedLocalEntities;
for (const exportedEntity of exportedLocalEntities.values()) {
this.analyze(exportedEntity);
}
}
_analyzeAstSymbol(astSymbol) {
if (astSymbol.analyzed) {
return;
}
if (astSymbol.nominalAnalysis) {
// We don't analyze nominal symbols
astSymbol._notifyAnalyzed();
return;
}
// Start at the root of the tree
const rootAstSymbol = astSymbol.rootAstSymbol;
// Calculate the full child tree for each definition
for (const astDeclaration of rootAstSymbol.astDeclarations) {
this._analyzeChildTree(astDeclaration.declaration, astDeclaration);
}
rootAstSymbol._notifyAnalyzed();
if (!astSymbol.isExternal) {
// If this symbol is non-external (i.e. it belongs to the working package), then we also analyze any
// referencedAstSymbols that are non-external. For example, this ensures that forgotten exports
// get analyzed.
rootAstSymbol.forEachDeclarationRecursive((astDeclaration) => {
for (const referencedAstEntity of astDeclaration.referencedAstEntities) {
// Walk up to the root of the tree, looking for any imports along the way
if (referencedAstEntity instanceof AstSymbol_1.AstSymbol) {
if (!referencedAstEntity.isExternal) {
this._analyzeAstSymbol(referencedAstEntity);
}
}
if (referencedAstEntity instanceof AstNamespaceImport_1.AstNamespaceImport) {
if (!referencedAstEntity.astModule.isExternal) {
this._analyzeAstNamespaceImport(referencedAstEntity);
}
}
}
});
}
}
/**
* Used by analyze to recursively analyze the entire child tree.
*/
_analyzeChildTree(node, governingAstDeclaration) {
switch (node.kind) {
case ts.SyntaxKind.JSDocComment: // Skip JSDoc comments - TS considers @param tags TypeReference nodes
return;
// Is this a reference to another AstSymbol?
case ts.SyntaxKind.TypeReference: // general type references
case ts.SyntaxKind.ExpressionWithTypeArguments: // special case for e.g. the "extends" keyword
case ts.SyntaxKind.ComputedPropertyName: // used for EcmaScript "symbols", e.g. "[toPrimitive]".
case ts.SyntaxKind.TypeQuery: // represents for "typeof X" as a type
{
// Sometimes the type reference will involve multiple identifiers, e.g. "a.b.C".
// In this case, we only need to worry about importing the first identifier,
// so do a depth-first search for it:
const identifierNode = TypeScriptHelpers_1.TypeScriptHelpers.findFirstChildNode(node, ts.SyntaxKind.Identifier);
if (identifierNode) {
let referencedAstEntity = this._entitiesByNode.get(identifierNode);
if (!referencedAstEntity) {
const symbol = this._typeChecker.getSymbolAtLocation(identifierNode);
if (!symbol) {
throw new Error('Symbol not found for identifier: ' + identifierNode.getText());
}
// Normally we expect getSymbolAtLocation() to take us to a declaration within the same source
// file, or else to an explicit "import" statement within the same source file. But in certain
// situations (e.g. a global variable) the symbol will refer to a declaration in some other
// source file. We'll call that case a "displaced symbol".
//
// For more info, see this discussion:
// https://github.com/microsoft/rushstack/issues/1765#issuecomment-595559849
let displacedSymbol = true;
for (const declaration of symbol.declarations || []) {
if (declaration.getSourceFile() === identifierNode.getSourceFile()) {
displacedSymbol = false;
break;
}
}
if (displacedSymbol) {
if (this._globalVariableAnalyzer.hasGlobalName(identifierNode.text)) {
// If the displaced symbol is a global variable, then API Extractor simply ignores it.
// Ambient declarations typically describe the runtime environment (provided by an API consumer),
// so we don't bother analyzing them as an API contract. (There are probably some packages
// that include interesting global variables in their API, but API Extractor doesn't support
// that yet; it would be a feature request.)
if (this._messageRouter.showDiagnostics) {
if (!this._alreadyWarnedGlobalNames.has(identifierNode.text)) {
this._alreadyWarnedGlobalNames.add(identifierNode.text);
this._messageRouter.logDiagnostic(`Ignoring reference to global variable "${identifierNode.text}"` +
` in ` +
SourceFileLocationFormatter_1.SourceFileLocationFormatter.formatDeclaration(identifierNode));
}
}
}
else {
// If you encounter this, please report a bug with a repro. We're interested to know
// how it can occur.
throw new node_core_library_1.InternalError(`Unable to follow symbol for "${identifierNode.text}"`);
}
}
else {
referencedAstEntity = this._exportAnalyzer.fetchReferencedAstEntity(symbol, governingAstDeclaration.astSymbol.isExternal);
this._entitiesByNode.set(identifierNode, referencedAstEntity);
}
}
if (referencedAstEntity) {
governingAstDeclaration._notifyReferencedAstEntity(referencedAstEntity);
}
}
}
break;
// Is this the identifier for the governingAstDeclaration?
case ts.SyntaxKind.Identifier:
{
const identifierNode = node;
if (!this._entitiesByNode.has(identifierNode)) {
const symbol = this._typeChecker.getSymbolAtLocation(identifierNode);
let referencedAstEntity = undefined;
if (symbol === governingAstDeclaration.astSymbol.followedSymbol) {
referencedAstEntity = this._fetchEntityForNode(identifierNode, governingAstDeclaration);
}
this._entitiesByNode.set(identifierNode, referencedAstEntity);
}
}
break;
case ts.SyntaxKind.ImportType:
{
const importTypeNode = node;
let referencedAstEntity = this._entitiesByNode.get(importTypeNode);
if (!this._entitiesByNode.has(importTypeNode)) {
referencedAstEntity = this._fetchEntityForNode(importTypeNode, governingAstDeclaration);
if (!referencedAstEntity) {
// This should never happen
throw new Error('Failed to fetch entity for import() type node: ' + importTypeNode.getText());
}
this._entitiesByNode.set(importTypeNode, referencedAstEntity);
}
if (referencedAstEntity) {
governingAstDeclaration._notifyReferencedAstEntity(referencedAstEntity);
}
}
break;
}
// Is this node declaring a new AstSymbol?
const newGoverningAstDeclaration = this._fetchAstDeclaration(node, governingAstDeclaration.astSymbol.isExternal);
for (const childNode of node.getChildren()) {
this._analyzeChildTree(childNode, newGoverningAstDeclaration || governingAstDeclaration);
}
}
_fetchEntityForNode(node, governingAstDeclaration) {
let referencedAstEntity = this._entitiesByNode.get(node);
if (!referencedAstEntity) {
if (node.kind === ts.SyntaxKind.ImportType) {
referencedAstEntity = this._exportAnalyzer.fetchReferencedAstEntityFromImportTypeNode(node, governingAstDeclaration.astSymbol.isExternal);
}
else {
const symbol = this._typeChecker.getSymbolAtLocation(node);
if (!symbol) {
throw new Error('Symbol not found for identifier: ' + node.getText());
}
referencedAstEntity = this._exportAnalyzer.fetchReferencedAstEntity(symbol, governingAstDeclaration.astSymbol.isExternal);
}
this._entitiesByNode.set(node, referencedAstEntity);
}
return referencedAstEntity;
}
_fetchAstDeclaration(node, isExternal) {
if (!AstDeclaration_1.AstDeclaration.isSupportedSyntaxKind(node.kind)) {
return undefined;
}
const symbol = TypeScriptHelpers_1.TypeScriptHelpers.getSymbolForDeclaration(node, this._typeChecker);
if (!symbol) {
throw new node_core_library_1.InternalError('Unable to find symbol for node');
}
const astSymbol = this._fetchAstSymbol({
followedSymbol: symbol,
isExternal: isExternal,
includeNominalAnalysis: true,
addIfMissing: true
});
if (!astSymbol) {
return undefined;
}
const astDeclaration = this._astDeclarationsByDeclaration.get(node);
if (!astDeclaration) {
throw new node_core_library_1.InternalError('Unable to find constructed AstDeclaration');
}
return astDeclaration;
}
_fetchAstSymbol(options) {
const followedSymbol = options.followedSymbol;
// Filter out symbols representing constructs that we don't care about
const arbitraryDeclaration = TypeScriptHelpers_1.TypeScriptHelpers.tryGetADeclaration(followedSymbol);
if (!arbitraryDeclaration) {
return undefined;
}
if (followedSymbol.flags &
(ts.SymbolFlags.TypeParameter | ts.SymbolFlags.TypeLiteral | ts.SymbolFlags.Transient)) {
if (!TypeScriptInternals_1.TypeScriptInternals.isLateBoundSymbol(followedSymbol)) {
return undefined;
}
}
// API Extractor doesn't analyze ambient declarations at all
if (TypeScriptHelpers_1.TypeScriptHelpers.isAmbient(followedSymbol, this._typeChecker)) {
// We make a special exemption for ambient declarations that appear in a source file containing
// an "export=" declaration that allows them to be imported as non-ambient.
if (!this._exportAnalyzer.isImportableAmbientSourceFile(arbitraryDeclaration.getSourceFile())) {
return undefined;
}
}
// Make sure followedSymbol isn't an alias for something else
if (TypeScriptHelpers_1.TypeScriptHelpers.isFollowableAlias(followedSymbol, this._typeChecker)) {
// We expect the caller to have already followed any aliases
throw new node_core_library_1.InternalError('AstSymbolTable._fetchAstSymbol() cannot be called with a symbol alias');
}
let astSymbol = this._astSymbolsBySymbol.get(followedSymbol);
if (!astSymbol) {
// None of the above lookups worked, so create a new entry...
let nominalAnalysis = false;
if (options.isExternal) {
// If the file is from an external package that does not support AEDoc, normally we ignore it completely.
// But in some cases (e.g. checking star exports of an external package) we need an AstSymbol to
// represent it, but we don't need to analyze its sibling/children.
const followedSymbolSourceFileName = arbitraryDeclaration.getSourceFile().fileName;
if (!this._packageMetadataManager.isAedocSupportedFor(followedSymbolSourceFileName)) {
nominalAnalysis = true;
if (!options.includeNominalAnalysis) {
return undefined;
}
}
}
let parentAstSymbol = undefined;
if (!nominalAnalysis) {
for (const declaration of followedSymbol.declarations || []) {
if (!AstDeclaration_1.AstDeclaration.isSupportedSyntaxKind(declaration.kind)) {
throw new node_core_library_1.InternalError(`The "${followedSymbol.name}" symbol has a` +
` ts.SyntaxKind.${ts.SyntaxKind[declaration.kind]} declaration which is not (yet?)` +
` supported by API Extractor`);
}
}
// We always fetch the entire chain of parents for each declaration.
// (Children/siblings are only analyzed on demand.)
// Key assumptions behind this squirrely logic:
//
// IF a given symbol has two declarations D1 and D2; AND
// If D1 has a parent P1, then
// - D2 will also have a parent P2; AND
// - P1 and P2's symbol will be the same
// - but P1 and P2 may be different (e.g. merged namespaces containing merged interfaces)
// Is there a parent AstSymbol? First we check to see if there is a parent declaration:
if (arbitraryDeclaration) {
const arbitraryParentDeclaration = this._tryFindFirstAstDeclarationParent(arbitraryDeclaration);
if (arbitraryParentDeclaration) {
const parentSymbol = TypeScriptHelpers_1.TypeScriptHelpers.getSymbolForDeclaration(arbitraryParentDeclaration, this._typeChecker);
parentAstSymbol = this._fetchAstSymbol({
followedSymbol: parentSymbol,
isExternal: options.isExternal,
includeNominalAnalysis: false,
addIfMissing: true
});
if (!parentAstSymbol) {
throw new node_core_library_1.InternalError('Unable to construct a parent AstSymbol for ' + followedSymbol.name);
}
}
}
}
const localName = options.localName || AstSymbolTable.getLocalNameForSymbol(followedSymbol);
astSymbol = new AstSymbol_1.AstSymbol({
followedSymbol: followedSymbol,
localName: localName,
isExternal: options.isExternal,
nominalAnalysis: nominalAnalysis,
parentAstSymbol: parentAstSymbol,
rootAstSymbol: parentAstSymbol ? parentAstSymbol.rootAstSymbol : undefined
});
this._astSymbolsBySymbol.set(followedSymbol, astSymbol);
// Okay, now while creating the declarations we will wire them up to the
// their corresponding parent declarations
for (const declaration of followedSymbol.declarations || []) {
let parentAstDeclaration = undefined;
if (parentAstSymbol) {
const parentDeclaration = this._tryFindFirstAstDeclarationParent(declaration);
if (!parentDeclaration) {
throw new node_core_library_1.InternalError('Missing parent declaration');
}
parentAstDeclaration = this._astDeclarationsByDeclaration.get(parentDeclaration);
if (!parentAstDeclaration) {
throw new node_core_library_1.InternalError('Missing parent AstDeclaration');
}
}
const astDeclaration = new AstDeclaration_1.AstDeclaration({
declaration,
astSymbol,
parent: parentAstDeclaration
});
this._astDeclarationsByDeclaration.set(declaration, astDeclaration);
}
}
if (options.isExternal !== astSymbol.isExternal) {
throw new node_core_library_1.InternalError(`Cannot assign isExternal=${options.isExternal} for` +
` the symbol ${astSymbol.localName} because it was previously registered` +
` with isExternal=${astSymbol.isExternal}`);
}
return astSymbol;
}
/**
* Returns the first parent satisfying isAstDeclaration(), or undefined if none is found.
*/
_tryFindFirstAstDeclarationParent(node) {
let currentNode = node.parent;
while (currentNode) {
if (AstDeclaration_1.AstDeclaration.isSupportedSyntaxKind(currentNode.kind)) {
return currentNode;
}
currentNode = currentNode.parent;
}
return undefined;
}
}
exports.AstSymbolTable = AstSymbolTable;
//# sourceMappingURL=AstSymbolTable.js.map
\ No newline at end of file
{"version":3,"file":"AstSymbolTable.js","sourceRoot":"","sources":["../../src/analyzer/AstSymbolTable.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/* eslint-disable no-bitwise */ // for ts.SymbolFlags\n\nimport * as ts from 'typescript';\n\nimport { type PackageJsonLookup, InternalError } from '@rushstack/node-core-library';\n\nimport { AstDeclaration } from './AstDeclaration';\nimport { TypeScriptHelpers } from './TypeScriptHelpers';\nimport { AstSymbol } from './AstSymbol';\nimport type { AstModule, IAstModuleExportInfo } from './AstModule';\nimport { PackageMetadataManager } from './PackageMetadataManager';\nimport { ExportAnalyzer } from './ExportAnalyzer';\nimport type { AstEntity } from './AstEntity';\nimport { AstNamespaceImport } from './AstNamespaceImport';\nimport type { MessageRouter } from '../collector/MessageRouter';\nimport { TypeScriptInternals, type IGlobalVariableAnalyzer } from './TypeScriptInternals';\nimport { SyntaxHelpers } from './SyntaxHelpers';\nimport { SourceFileLocationFormatter } from './SourceFileLocationFormatter';\n\n/**\n * Options for `AstSymbolTable._fetchAstSymbol()`\n */\nexport interface IFetchAstSymbolOptions {\n /**\n * The symbol after any symbol aliases have been followed using TypeScriptHelpers.followAliases()\n */\n followedSymbol: ts.Symbol;\n /**\n * True if followedSymbol is not part of the working package\n */\n isExternal: boolean;\n\n /**\n * If true, symbols with AstSymbol.nominalAnalysis=true will be returned.\n * Otherwise `undefined` will be returned for such symbols.\n */\n includeNominalAnalysis: boolean;\n\n /**\n * True while populating the `AstSymbolTable`; false if we're doing a passive lookup\n * without adding anything new to the table\n */\n addIfMissing: boolean;\n\n /**\n * A hint to help `_fetchAstSymbol()` determine the `AstSymbol.localName`.\n */\n localName?: string;\n}\n\n/**\n * AstSymbolTable is the workhorse that builds AstSymbol and AstDeclaration objects.\n * It maintains a cache of already constructed objects. AstSymbolTable constructs\n * AstModule objects, but otherwise the state that it maintains is agnostic of\n * any particular entry point. (For example, it does not track whether a given AstSymbol\n * is \"exported\" or not.)\n *\n * Internally, AstSymbolTable relies on ExportAnalyzer to crawl import statements and determine where symbols\n * are declared (i.e. the AstImport information needed to import them).\n */\nexport class AstSymbolTable {\n private readonly _program: ts.Program;\n private readonly _typeChecker: ts.TypeChecker;\n private readonly _messageRouter: MessageRouter;\n private readonly _globalVariableAnalyzer: IGlobalVariableAnalyzer;\n private readonly _packageMetadataManager: PackageMetadataManager;\n private readonly _exportAnalyzer: ExportAnalyzer;\n private readonly _alreadyWarnedGlobalNames: Set<string>;\n\n /**\n * A mapping from ts.Symbol --> AstSymbol\n * NOTE: The AstSymbol.followedSymbol will always be a lookup key, but additional keys\n * are possible.\n *\n * After following type aliases, we use this map to look up the corresponding AstSymbol.\n */\n private readonly _astSymbolsBySymbol: Map<ts.Symbol, AstSymbol> = new Map<ts.Symbol, AstSymbol>();\n\n /**\n * A mapping from ts.Declaration --> AstDeclaration\n */\n private readonly _astDeclarationsByDeclaration: Map<ts.Node, AstDeclaration> = new Map<\n ts.Node,\n AstDeclaration\n >();\n\n // Note that this is a mapping from specific AST nodes that we analyzed, based on the underlying symbol\n // for that node.\n private readonly _entitiesByNode: Map<ts.Identifier | ts.ImportTypeNode, AstEntity | undefined> = new Map<\n ts.Identifier,\n AstEntity | undefined\n >();\n\n public constructor(\n program: ts.Program,\n typeChecker: ts.TypeChecker,\n packageJsonLookup: PackageJsonLookup,\n bundledPackageNames: ReadonlySet<string>,\n messageRouter: MessageRouter\n ) {\n this._program = program;\n this._typeChecker = typeChecker;\n this._messageRouter = messageRouter;\n this._globalVariableAnalyzer = TypeScriptInternals.getGlobalVariableAnalyzer(program);\n this._packageMetadataManager = new PackageMetadataManager(packageJsonLookup, messageRouter);\n\n this._exportAnalyzer = new ExportAnalyzer(this._program, this._typeChecker, bundledPackageNames, {\n analyze: this.analyze.bind(this),\n fetchAstSymbol: this._fetchAstSymbol.bind(this)\n });\n\n this._alreadyWarnedGlobalNames = new Set<string>();\n }\n\n /**\n * Used to analyze an entry point that belongs to the working package.\n */\n public fetchAstModuleFromWorkingPackage(sourceFile: ts.SourceFile): AstModule {\n return this._exportAnalyzer.fetchAstModuleFromSourceFile(sourceFile, undefined, false);\n }\n\n /**\n * This crawls the specified entry point and collects the full set of exported AstSymbols.\n */\n public fetchAstModuleExportInfo(astModule: AstModule): IAstModuleExportInfo {\n return this._exportAnalyzer.fetchAstModuleExportInfo(astModule);\n }\n\n /**\n * Attempts to retrieve an export by name from the specified `AstModule`.\n * Returns undefined if no match was found.\n */\n public tryGetExportOfAstModule(exportName: string, astModule: AstModule): AstEntity | undefined {\n return this._exportAnalyzer.tryGetExportOfAstModule(exportName, astModule);\n }\n\n /**\n * Ensures that AstSymbol.analyzed is true for the provided symbol. The operation\n * starts from the root symbol and then fills out all children of all declarations, and\n * also calculates AstDeclaration.referencedAstSymbols for all declarations.\n * If the symbol is not imported, any non-imported references are also analyzed.\n *\n * @remarks\n * This is an expensive operation, so we only perform it for top-level exports of an\n * the AstModule. For example, if some code references a nested class inside\n * a namespace from another library, we do not analyze any of that class's siblings\n * or members. (We do always construct its parents however, since AstDefinition.parent\n * is immutable, and needed e.g. to calculate release tag inheritance.)\n */\n public analyze(astEntity: AstEntity): void {\n if (astEntity instanceof AstSymbol) {\n return this._analyzeAstSymbol(astEntity);\n }\n\n if (astEntity instanceof AstNamespaceImport) {\n return this._analyzeAstNamespaceImport(astEntity);\n }\n }\n\n /**\n * For a given astDeclaration, this efficiently finds the child corresponding to the\n * specified ts.Node. It is assumed that AstDeclaration.isSupportedSyntaxKind() would return true for\n * that node type, and that the node is an immediate child of the provided AstDeclaration.\n */\n // NOTE: This could be a method of AstSymbol if it had a backpointer to its AstSymbolTable.\n public getChildAstDeclarationByNode(node: ts.Node, parentAstDeclaration: AstDeclaration): AstDeclaration {\n if (!parentAstDeclaration.astSymbol.analyzed) {\n throw new Error('getChildDeclarationByNode() cannot be used for an AstSymbol that was not analyzed');\n }\n\n const childAstDeclaration: AstDeclaration | undefined = this._astDeclarationsByDeclaration.get(node);\n if (!childAstDeclaration) {\n throw new Error('Child declaration not found for the specified node');\n }\n if (childAstDeclaration.parent !== parentAstDeclaration) {\n throw new InternalError('The found child is not attached to the parent AstDeclaration');\n }\n\n return childAstDeclaration;\n }\n\n /**\n * For a given ts.Identifier that is part of an AstSymbol that we analyzed, return the AstEntity that\n * it refers to. Returns undefined if it doesn't refer to anything interesting.\n * @remarks\n * Throws an Error if the ts.Identifier is not part of node tree that was analyzed.\n */\n public tryGetEntityForNode(identifier: ts.Identifier | ts.ImportTypeNode): AstEntity | undefined {\n if (!this._entitiesByNode.has(identifier)) {\n throw new InternalError('tryGetEntityForIdentifier() called for an identifier that was not analyzed');\n }\n return this._entitiesByNode.get(identifier);\n }\n\n /**\n * Builds an AstSymbol.localName for a given ts.Symbol. In the current implementation, the localName is\n * a TypeScript-like expression that may be a string literal or ECMAScript symbol expression.\n *\n * ```ts\n * class X {\n * // localName=\"identifier\"\n * public identifier: number = 1;\n * // localName=\"\\\"identifier\\\"\"\n * public \"quoted string!\": number = 2;\n * // localName=\"[MyNamespace.MySymbol]\"\n * public [MyNamespace.MySymbol]: number = 3;\n * }\n * ```\n */\n public static getLocalNameForSymbol(symbol: ts.Symbol): string {\n // TypeScript binds well-known ECMAScript symbols like \"[Symbol.iterator]\" as \"__@iterator\".\n // Decode it back into \"[Symbol.iterator]\".\n const wellKnownSymbolName: string | undefined = TypeScriptHelpers.tryDecodeWellKnownSymbolName(\n symbol.escapedName\n );\n if (wellKnownSymbolName) {\n return wellKnownSymbolName;\n }\n\n const isUniqueSymbol: boolean = TypeScriptHelpers.isUniqueSymbolName(symbol.escapedName);\n\n // We will try to obtain the name from a declaration; otherwise we'll fall back to the symbol name.\n let unquotedName: string = symbol.name;\n\n for (const declaration of symbol.declarations || []) {\n // Handle cases such as \"export default class X { }\" where the symbol name is \"default\"\n // but the local name is \"X\".\n const localSymbol: ts.Symbol | undefined = TypeScriptInternals.tryGetLocalSymbol(declaration);\n if (localSymbol) {\n unquotedName = localSymbol.name;\n }\n\n // If it is a non-well-known symbol, then return the late-bound name. For example, \"X.Y.z\" in this example:\n //\n // namespace X {\n // export namespace Y {\n // export const z: unique symbol = Symbol(\"z\");\n // }\n // }\n //\n // class C {\n // public [X.Y.z](): void { }\n // }\n //\n if (isUniqueSymbol) {\n const declarationName: ts.DeclarationName | undefined = ts.getNameOfDeclaration(declaration);\n if (declarationName && ts.isComputedPropertyName(declarationName)) {\n const lateBoundName: string | undefined = TypeScriptHelpers.tryGetLateBoundName(declarationName);\n if (lateBoundName) {\n // Here the string may contain an expression such as \"[X.Y.z]\". Names starting with \"[\" are always\n // expressions. If a string literal contains those characters, the code below will JSON.stringify() it\n // to avoid a collision.\n return lateBoundName;\n }\n }\n }\n }\n\n // Otherwise that name may come from a quoted string or pseudonym like `__constructor`.\n // If the string is not a safe identifier, then we must add quotes.\n // Note that if it was quoted but did not need to be quoted, here we will remove the quotes.\n if (!SyntaxHelpers.isSafeUnquotedMemberIdentifier(unquotedName)) {\n // For API Extractor's purposes, a canonical form is more appropriate than trying to reflect whatever\n // appeared in the source code. The code is not even guaranteed to be consistent, for example:\n //\n // class X {\n // public \"f1\"(x: string): void;\n // public f1(x: boolean): void;\n // public 'f1'(x: string | boolean): void { }\n // }\n return JSON.stringify(unquotedName);\n }\n\n return unquotedName;\n }\n\n private _analyzeAstNamespaceImport(astNamespaceImport: AstNamespaceImport): void {\n if (astNamespaceImport.analyzed) {\n return;\n }\n\n // mark before actual analyzing, to handle module cyclic reexport\n astNamespaceImport.analyzed = true;\n\n const exportedLocalEntities: Map<string, AstEntity> = this.fetchAstModuleExportInfo(\n astNamespaceImport.astModule\n ).exportedLocalEntities;\n\n for (const exportedEntity of exportedLocalEntities.values()) {\n this.analyze(exportedEntity);\n }\n }\n\n private _analyzeAstSymbol(astSymbol: AstSymbol): void {\n if (astSymbol.analyzed) {\n return;\n }\n\n if (astSymbol.nominalAnalysis) {\n // We don't analyze nominal symbols\n astSymbol._notifyAnalyzed();\n return;\n }\n\n // Start at the root of the tree\n const rootAstSymbol: AstSymbol = astSymbol.rootAstSymbol;\n\n // Calculate the full child tree for each definition\n for (const astDeclaration of rootAstSymbol.astDeclarations) {\n this._analyzeChildTree(astDeclaration.declaration, astDeclaration);\n }\n\n rootAstSymbol._notifyAnalyzed();\n\n if (!astSymbol.isExternal) {\n // If this symbol is non-external (i.e. it belongs to the working package), then we also analyze any\n // referencedAstSymbols that are non-external. For example, this ensures that forgotten exports\n // get analyzed.\n rootAstSymbol.forEachDeclarationRecursive((astDeclaration: AstDeclaration) => {\n for (const referencedAstEntity of astDeclaration.referencedAstEntities) {\n // Walk up to the root of the tree, looking for any imports along the way\n if (referencedAstEntity instanceof AstSymbol) {\n if (!referencedAstEntity.isExternal) {\n this._analyzeAstSymbol(referencedAstEntity);\n }\n }\n\n if (referencedAstEntity instanceof AstNamespaceImport) {\n if (!referencedAstEntity.astModule.isExternal) {\n this._analyzeAstNamespaceImport(referencedAstEntity);\n }\n }\n }\n });\n }\n }\n\n /**\n * Used by analyze to recursively analyze the entire child tree.\n */\n private _analyzeChildTree(node: ts.Node, governingAstDeclaration: AstDeclaration): void {\n switch (node.kind) {\n case ts.SyntaxKind.JSDocComment: // Skip JSDoc comments - TS considers @param tags TypeReference nodes\n return;\n\n // Is this a reference to another AstSymbol?\n case ts.SyntaxKind.TypeReference: // general type references\n case ts.SyntaxKind.ExpressionWithTypeArguments: // special case for e.g. the \"extends\" keyword\n case ts.SyntaxKind.ComputedPropertyName: // used for EcmaScript \"symbols\", e.g. \"[toPrimitive]\".\n case ts.SyntaxKind.TypeQuery: // represents for \"typeof X\" as a type\n {\n // Sometimes the type reference will involve multiple identifiers, e.g. \"a.b.C\".\n // In this case, we only need to worry about importing the first identifier,\n // so do a depth-first search for it:\n const identifierNode: ts.Identifier | undefined = TypeScriptHelpers.findFirstChildNode(\n node,\n ts.SyntaxKind.Identifier\n );\n\n if (identifierNode) {\n let referencedAstEntity: AstEntity | undefined = this._entitiesByNode.get(identifierNode);\n if (!referencedAstEntity) {\n const symbol: ts.Symbol | undefined = this._typeChecker.getSymbolAtLocation(identifierNode);\n if (!symbol) {\n throw new Error('Symbol not found for identifier: ' + identifierNode.getText());\n }\n\n // Normally we expect getSymbolAtLocation() to take us to a declaration within the same source\n // file, or else to an explicit \"import\" statement within the same source file. But in certain\n // situations (e.g. a global variable) the symbol will refer to a declaration in some other\n // source file. We'll call that case a \"displaced symbol\".\n //\n // For more info, see this discussion:\n // https://github.com/microsoft/rushstack/issues/1765#issuecomment-595559849\n let displacedSymbol: boolean = true;\n for (const declaration of symbol.declarations || []) {\n if (declaration.getSourceFile() === identifierNode.getSourceFile()) {\n displacedSymbol = false;\n break;\n }\n }\n\n if (displacedSymbol) {\n if (this._globalVariableAnalyzer.hasGlobalName(identifierNode.text)) {\n // If the displaced symbol is a global variable, then API Extractor simply ignores it.\n // Ambient declarations typically describe the runtime environment (provided by an API consumer),\n // so we don't bother analyzing them as an API contract. (There are probably some packages\n // that include interesting global variables in their API, but API Extractor doesn't support\n // that yet; it would be a feature request.)\n\n if (this._messageRouter.showDiagnostics) {\n if (!this._alreadyWarnedGlobalNames.has(identifierNode.text)) {\n this._alreadyWarnedGlobalNames.add(identifierNode.text);\n this._messageRouter.logDiagnostic(\n `Ignoring reference to global variable \"${identifierNode.text}\"` +\n ` in ` +\n SourceFileLocationFormatter.formatDeclaration(identifierNode)\n );\n }\n }\n } else {\n // If you encounter this, please report a bug with a repro. We're interested to know\n // how it can occur.\n throw new InternalError(`Unable to follow symbol for \"${identifierNode.text}\"`);\n }\n } else {\n referencedAstEntity = this._exportAnalyzer.fetchReferencedAstEntity(\n symbol,\n governingAstDeclaration.astSymbol.isExternal\n );\n\n this._entitiesByNode.set(identifierNode, referencedAstEntity);\n }\n }\n\n if (referencedAstEntity) {\n governingAstDeclaration._notifyReferencedAstEntity(referencedAstEntity);\n }\n }\n }\n break;\n\n // Is this the identifier for the governingAstDeclaration?\n case ts.SyntaxKind.Identifier:\n {\n const identifierNode: ts.Identifier = node as ts.Identifier;\n if (!this._entitiesByNode.has(identifierNode)) {\n const symbol: ts.Symbol | undefined = this._typeChecker.getSymbolAtLocation(identifierNode);\n\n let referencedAstEntity: AstEntity | undefined = undefined;\n\n if (symbol === governingAstDeclaration.astSymbol.followedSymbol) {\n referencedAstEntity = this._fetchEntityForNode(identifierNode, governingAstDeclaration);\n }\n\n this._entitiesByNode.set(identifierNode, referencedAstEntity);\n }\n }\n break;\n\n case ts.SyntaxKind.ImportType:\n {\n const importTypeNode: ts.ImportTypeNode = node as ts.ImportTypeNode;\n let referencedAstEntity: AstEntity | undefined = this._entitiesByNode.get(importTypeNode);\n\n if (!this._entitiesByNode.has(importTypeNode)) {\n referencedAstEntity = this._fetchEntityForNode(importTypeNode, governingAstDeclaration);\n\n if (!referencedAstEntity) {\n // This should never happen\n throw new Error('Failed to fetch entity for import() type node: ' + importTypeNode.getText());\n }\n\n this._entitiesByNode.set(importTypeNode, referencedAstEntity);\n }\n\n if (referencedAstEntity) {\n governingAstDeclaration._notifyReferencedAstEntity(referencedAstEntity);\n }\n }\n break;\n }\n\n // Is this node declaring a new AstSymbol?\n const newGoverningAstDeclaration: AstDeclaration | undefined = this._fetchAstDeclaration(\n node,\n governingAstDeclaration.astSymbol.isExternal\n );\n\n for (const childNode of node.getChildren()) {\n this._analyzeChildTree(childNode, newGoverningAstDeclaration || governingAstDeclaration);\n }\n }\n\n private _fetchEntityForNode(\n node: ts.Identifier | ts.ImportTypeNode,\n governingAstDeclaration: AstDeclaration\n ): AstEntity | undefined {\n let referencedAstEntity: AstEntity | undefined = this._entitiesByNode.get(node);\n if (!referencedAstEntity) {\n if (node.kind === ts.SyntaxKind.ImportType) {\n referencedAstEntity = this._exportAnalyzer.fetchReferencedAstEntityFromImportTypeNode(\n node,\n governingAstDeclaration.astSymbol.isExternal\n );\n } else {\n const symbol: ts.Symbol | undefined = this._typeChecker.getSymbolAtLocation(node);\n if (!symbol) {\n throw new Error('Symbol not found for identifier: ' + node.getText());\n }\n\n referencedAstEntity = this._exportAnalyzer.fetchReferencedAstEntity(\n symbol,\n governingAstDeclaration.astSymbol.isExternal\n );\n }\n\n this._entitiesByNode.set(node, referencedAstEntity);\n }\n return referencedAstEntity;\n }\n\n private _fetchAstDeclaration(node: ts.Node, isExternal: boolean): AstDeclaration | undefined {\n if (!AstDeclaration.isSupportedSyntaxKind(node.kind)) {\n return undefined;\n }\n\n const symbol: ts.Symbol | undefined = TypeScriptHelpers.getSymbolForDeclaration(\n node as ts.Declaration,\n this._typeChecker\n );\n if (!symbol) {\n throw new InternalError('Unable to find symbol for node');\n }\n\n const astSymbol: AstSymbol | undefined = this._fetchAstSymbol({\n followedSymbol: symbol,\n isExternal: isExternal,\n includeNominalAnalysis: true,\n addIfMissing: true\n });\n\n if (!astSymbol) {\n return undefined;\n }\n\n const astDeclaration: AstDeclaration | undefined = this._astDeclarationsByDeclaration.get(node);\n\n if (!astDeclaration) {\n throw new InternalError('Unable to find constructed AstDeclaration');\n }\n\n return astDeclaration;\n }\n\n private _fetchAstSymbol(options: IFetchAstSymbolOptions): AstSymbol | undefined {\n const followedSymbol: ts.Symbol = options.followedSymbol;\n\n // Filter out symbols representing constructs that we don't care about\n const arbitraryDeclaration: ts.Declaration | undefined =\n TypeScriptHelpers.tryGetADeclaration(followedSymbol);\n if (!arbitraryDeclaration) {\n return undefined;\n }\n\n if (\n followedSymbol.flags &\n (ts.SymbolFlags.TypeParameter | ts.SymbolFlags.TypeLiteral | ts.SymbolFlags.Transient)\n ) {\n if (!TypeScriptInternals.isLateBoundSymbol(followedSymbol)) {\n return undefined;\n }\n }\n\n // API Extractor doesn't analyze ambient declarations at all\n if (TypeScriptHelpers.isAmbient(followedSymbol, this._typeChecker)) {\n // We make a special exemption for ambient declarations that appear in a source file containing\n // an \"export=\" declaration that allows them to be imported as non-ambient.\n if (!this._exportAnalyzer.isImportableAmbientSourceFile(arbitraryDeclaration.getSourceFile())) {\n return undefined;\n }\n }\n\n // Make sure followedSymbol isn't an alias for something else\n if (TypeScriptHelpers.isFollowableAlias(followedSymbol, this._typeChecker)) {\n // We expect the caller to have already followed any aliases\n throw new InternalError('AstSymbolTable._fetchAstSymbol() cannot be called with a symbol alias');\n }\n\n let astSymbol: AstSymbol | undefined = this._astSymbolsBySymbol.get(followedSymbol);\n\n if (!astSymbol) {\n // None of the above lookups worked, so create a new entry...\n let nominalAnalysis: boolean = false;\n\n if (options.isExternal) {\n // If the file is from an external package that does not support AEDoc, normally we ignore it completely.\n // But in some cases (e.g. checking star exports of an external package) we need an AstSymbol to\n // represent it, but we don't need to analyze its sibling/children.\n const followedSymbolSourceFileName: string = arbitraryDeclaration.getSourceFile().fileName;\n\n if (!this._packageMetadataManager.isAedocSupportedFor(followedSymbolSourceFileName)) {\n nominalAnalysis = true;\n\n if (!options.includeNominalAnalysis) {\n return undefined;\n }\n }\n }\n\n let parentAstSymbol: AstSymbol | undefined = undefined;\n\n if (!nominalAnalysis) {\n for (const declaration of followedSymbol.declarations || []) {\n if (!AstDeclaration.isSupportedSyntaxKind(declaration.kind)) {\n throw new InternalError(\n `The \"${followedSymbol.name}\" symbol has a` +\n ` ts.SyntaxKind.${ts.SyntaxKind[declaration.kind]} declaration which is not (yet?)` +\n ` supported by API Extractor`\n );\n }\n }\n\n // We always fetch the entire chain of parents for each declaration.\n // (Children/siblings are only analyzed on demand.)\n\n // Key assumptions behind this squirrely logic:\n //\n // IF a given symbol has two declarations D1 and D2; AND\n // If D1 has a parent P1, then\n // - D2 will also have a parent P2; AND\n // - P1 and P2's symbol will be the same\n // - but P1 and P2 may be different (e.g. merged namespaces containing merged interfaces)\n\n // Is there a parent AstSymbol? First we check to see if there is a parent declaration:\n if (arbitraryDeclaration) {\n const arbitraryParentDeclaration: ts.Node | undefined =\n this._tryFindFirstAstDeclarationParent(arbitraryDeclaration);\n\n if (arbitraryParentDeclaration) {\n const parentSymbol: ts.Symbol = TypeScriptHelpers.getSymbolForDeclaration(\n arbitraryParentDeclaration as ts.Declaration,\n this._typeChecker\n );\n\n parentAstSymbol = this._fetchAstSymbol({\n followedSymbol: parentSymbol,\n isExternal: options.isExternal,\n includeNominalAnalysis: false,\n addIfMissing: true\n });\n if (!parentAstSymbol) {\n throw new InternalError('Unable to construct a parent AstSymbol for ' + followedSymbol.name);\n }\n }\n }\n }\n\n const localName: string | undefined =\n options.localName || AstSymbolTable.getLocalNameForSymbol(followedSymbol);\n\n astSymbol = new AstSymbol({\n followedSymbol: followedSymbol,\n localName: localName,\n isExternal: options.isExternal,\n nominalAnalysis: nominalAnalysis,\n parentAstSymbol: parentAstSymbol,\n rootAstSymbol: parentAstSymbol ? parentAstSymbol.rootAstSymbol : undefined\n });\n\n this._astSymbolsBySymbol.set(followedSymbol, astSymbol);\n\n // Okay, now while creating the declarations we will wire them up to the\n // their corresponding parent declarations\n for (const declaration of followedSymbol.declarations || []) {\n let parentAstDeclaration: AstDeclaration | undefined = undefined;\n if (parentAstSymbol) {\n const parentDeclaration: ts.Node | undefined = this._tryFindFirstAstDeclarationParent(declaration);\n\n if (!parentDeclaration) {\n throw new InternalError('Missing parent declaration');\n }\n\n parentAstDeclaration = this._astDeclarationsByDeclaration.get(parentDeclaration);\n if (!parentAstDeclaration) {\n throw new InternalError('Missing parent AstDeclaration');\n }\n }\n\n const astDeclaration: AstDeclaration = new AstDeclaration({\n declaration,\n astSymbol,\n parent: parentAstDeclaration\n });\n\n this._astDeclarationsByDeclaration.set(declaration, astDeclaration);\n }\n }\n\n if (options.isExternal !== astSymbol.isExternal) {\n throw new InternalError(\n `Cannot assign isExternal=${options.isExternal} for` +\n ` the symbol ${astSymbol.localName} because it was previously registered` +\n ` with isExternal=${astSymbol.isExternal}`\n );\n }\n\n return astSymbol;\n }\n\n /**\n * Returns the first parent satisfying isAstDeclaration(), or undefined if none is found.\n */\n private _tryFindFirstAstDeclarationParent(node: ts.Node): ts.Node | undefined {\n let currentNode: ts.Node | undefined = node.parent;\n while (currentNode) {\n if (AstDeclaration.isSupportedSyntaxKind(currentNode.kind)) {\n return currentNode;\n }\n currentNode = currentNode.parent;\n }\n return undefined;\n }\n}\n"]}
\ No newline at end of file
import * as ts from 'typescript';
import { AstSymbol } from './AstSymbol';
import { AstModule, type IAstModuleExportInfo } from './AstModule';
import type { IFetchAstSymbolOptions } from './AstSymbolTable';
import type { AstEntity } from './AstEntity';
/**
* Exposes the minimal APIs from AstSymbolTable that are needed by ExportAnalyzer.
*
* In particular, we want ExportAnalyzer to be able to call AstSymbolTable._fetchAstSymbol() even though it
* is a very private API that should not be exposed to any other components.
*/
export interface IAstSymbolTable {
fetchAstSymbol(options: IFetchAstSymbolOptions): AstSymbol | undefined;
analyze(astEntity: AstEntity): void;
}
/**
* Used with ExportAnalyzer.fetchAstModuleBySourceFile() to provide contextual information about how the source file
* was imported.
*/
interface IAstModuleReference {
/**
* For example, if we are following a statement like `import { X } from 'some-package'`, this will be the
* string `"some-package"`.
*/
moduleSpecifier: string;
/**
* For example, if we are following a statement like `import { X } from 'some-package'`, this will be the
* symbol for `X`.
*/
moduleSpecifierSymbol: ts.Symbol;
}
/**
* The ExportAnalyzer is an internal part of AstSymbolTable that has been moved out into its own source file
* because it is a complex and mostly self-contained algorithm.
*
* Its job is to build up AstModule objects by crawling import statements to discover where declarations come from.
* This is conceptually the same as the compiler's own TypeChecker.getExportsOfModule(), except that when
* ExportAnalyzer encounters a declaration that was imported from an external package, it remembers how it was imported
* (i.e. the AstImport object). Today the compiler API does not expose this information, which is crucial for
* generating .d.ts rollups.
*/
export declare class ExportAnalyzer {
private readonly _program;
private readonly _typeChecker;
private readonly _bundledPackageNames;
private readonly _astSymbolTable;
private readonly _astModulesByModuleSymbol;
private readonly _importableAmbientSourceFiles;
private readonly _astImportsByKey;
private readonly _astNamespaceImportByModule;
constructor(program: ts.Program, typeChecker: ts.TypeChecker, bundledPackageNames: ReadonlySet<string>, astSymbolTable: IAstSymbolTable);
/**
* For a given source file, this analyzes all of its exports and produces an AstModule object.
*
* @param moduleReference - contextual information about the import statement that took us to this source file.
* or `undefined` if this source file is the initial entry point
* @param isExternal - whether the given `moduleReference` is external.
*/
fetchAstModuleFromSourceFile(sourceFile: ts.SourceFile, moduleReference: IAstModuleReference | undefined, isExternal: boolean): AstModule;
/**
* Retrieves the symbol for the module corresponding to the ts.SourceFile that is being imported/exported.
*
* @remarks
* The `module` keyword can be used to declare multiple TypeScript modules inside a single source file.
* (This is a deprecated construct and mainly used for typings such as `@types/node`.) In this situation,
* `moduleReference` helps us to fish out the correct module symbol.
*/
private _getModuleSymbolFromSourceFile;
/**
* Implementation of {@link AstSymbolTable.fetchAstModuleExportInfo}.
*/
fetchAstModuleExportInfo(entryPointAstModule: AstModule): IAstModuleExportInfo;
/**
* Returns true if the module specifier refers to an external package. Ignores packages listed in the
* "bundledPackages" setting from the api-extractor.json config file.
*/
private _isExternalModulePath;
/**
* Returns true if when we analyzed sourceFile, we found that it contains an "export=" statement that allows
* it to behave /either/ as an ambient module /or/ as a regular importable module. In this case,
* `AstSymbolTable._fetchAstSymbol()` will analyze its symbols even though `TypeScriptHelpers.isAmbient()`
* returns true.
*/
isImportableAmbientSourceFile(sourceFile: ts.SourceFile): boolean;
private _collectAllExportsRecursive;
/**
* For a given symbol (which was encountered in the specified sourceFile), this fetches the AstEntity that it
* refers to. For example, if a particular interface describes the return value of a function, this API can help
* us determine a TSDoc declaration reference for that symbol (if the symbol is exported).
*/
fetchReferencedAstEntity(symbol: ts.Symbol, referringModuleIsExternal: boolean): AstEntity | undefined;
fetchReferencedAstEntityFromImportTypeNode(node: ts.ImportTypeNode, referringModuleIsExternal: boolean): AstEntity | undefined;
private _tryMatchExportDeclaration;
private _getAstNamespaceExport;
private _tryMatchImportDeclaration;
private _getAstNamespaceImport;
private static _getIsTypeOnly;
private _getExportOfSpecifierAstModule;
private _getExportOfAstModule;
/**
* Implementation of {@link AstSymbolTable.tryGetExportOfAstModule}.
*/
tryGetExportOfAstModule(exportName: string, astModule: AstModule): AstEntity | undefined;
private _tryGetExportOfAstModule;
private _tryGetExternalModulePath;
/**
* Given an ImportDeclaration of the form `export { X } from "___";`, this interprets the module specifier (`"___"`)
* and fetches the corresponding AstModule object.
*/
private _fetchSpecifierAstModule;
private _fetchAstImport;
private _getModuleSpecifier;
}
export {};
//# sourceMappingURL=ExportAnalyzer.d.ts.map
\ No newline at end of file
{"version":3,"file":"ExportAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/ExportAnalyzer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAKjC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGnE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAK7C;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS,GAAG,SAAS,CAAC;IAEvE,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;CACrC;AAED;;;GAGG;AACH,UAAU,mBAAmB;IAC3B;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,qBAAqB,EAAE,EAAE,CAAC,MAAM,CAAC;CAClC;AAED;;;;;;;;;GASG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiB;IAC9C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAsB;IAC3D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAElD,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAA8D;IAGxG,OAAO,CAAC,QAAQ,CAAC,6BAA6B,CAAgD;IAE9F,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAwD;IACzF,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAiD;gBAG3F,OAAO,EAAE,EAAE,CAAC,OAAO,EACnB,WAAW,EAAE,EAAE,CAAC,WAAW,EAC3B,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,EACxC,cAAc,EAAE,eAAe;IAQjC;;;;;;OAMG;IACI,4BAA4B,CACjC,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,eAAe,EAAE,mBAAmB,GAAG,SAAS,EAChD,UAAU,EAAE,OAAO,GAClB,SAAS;IAoFZ;;;;;;;OAOG;IACH,OAAO,CAAC,8BAA8B;IAiDtC;;OAEG;IACI,wBAAwB,CAAC,mBAAmB,EAAE,SAAS,GAAG,oBAAoB;IAmBrF;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAmD7B;;;;;OAKG;IACI,6BAA6B,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,OAAO;IAIxE,OAAO,CAAC,2BAA2B;IA6CnC;;;;OAIG;IACI,wBAAwB,CAC7B,MAAM,EAAE,EAAE,CAAC,MAAM,EACjB,yBAAyB,EAAE,OAAO,GACjC,SAAS,GAAG,SAAS;IA4DjB,0CAA0C,CAC/C,IAAI,EAAE,EAAE,CAAC,cAAc,EACvB,yBAAyB,EAAE,OAAO,GACjC,SAAS,GAAG,SAAS;IA0FxB,OAAO,CAAC,0BAA0B;IA0ElC,OAAO,CAAC,sBAAsB;IAmB9B,OAAO,CAAC,0BAA0B;IA0JlC,OAAO,CAAC,sBAAsB;IAmB9B,OAAO,CAAC,MAAM,CAAC,cAAc;IAO7B,OAAO,CAAC,8BAA8B;IAatC,OAAO,CAAC,qBAAqB;IAe7B;;OAEG;IACI,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS;IAK/F,OAAO,CAAC,wBAAwB;IAoDhC,OAAO,CAAC,yBAAyB;IAWjC;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IA6DhC,OAAO,CAAC,eAAe;IA8BvB,OAAO,CAAC,mBAAmB;CAgB5B"}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment