Skip to content

Commit

Permalink
Merge pull request microsoft#1337 from rbuckton/deeplyLinkedtypes
Browse files Browse the repository at this point in the history
[api-extractor] Deeply linked types
  • Loading branch information
octogonz authored Sep 10, 2019
2 parents 9ec48a5 + 57c631f commit 8af485a
Show file tree
Hide file tree
Showing 5 changed files with 380 additions and 16 deletions.
8 changes: 3 additions & 5 deletions src/analyzer/AstSymbolTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,19 +227,17 @@ export class AstSymbolTable {
* ```
*/
public static getLocalNameForSymbol(symbol: ts.Symbol): string {
const symbolName: string = symbol.name;

// TypeScript binds well-known ECMAScript symbols like "[Symbol.iterator]" as "__@iterator".
// Decode it back into "[Symbol.iterator]".
const wellKnownSymbolName: string | undefined = TypeScriptHelpers.tryDecodeWellKnownSymbolName(symbolName);
const wellKnownSymbolName: string | undefined = TypeScriptHelpers.tryDecodeWellKnownSymbolName(symbol.escapedName);
if (wellKnownSymbolName) {
return wellKnownSymbolName;
}

const isUniqueSymbol: boolean = TypeScriptHelpers.isUniqueSymbolName(symbolName);
const isUniqueSymbol: boolean = 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: string = symbolName;
let unquotedName: string = symbol.name;

for (const declaration of symbol.declarations || []) {
// Handle cases such as "export default class X { }" where the symbol name is "default"
Expand Down
8 changes: 4 additions & 4 deletions src/analyzer/TypeScriptHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ export class TypeScriptHelpers {
* If `name` is of this form, then `tryGetWellKnownSymbolName()` converts it back into e.g. `[Symbol.iterator]`.
* If the string does not start with `__@` then `undefined` is returned.
*/
public static tryDecodeWellKnownSymbolName(name: string): string | undefined {
const match: RegExpExecArray | null = TypeScriptHelpers._wellKnownSymbolNameRegExp.exec(name);
public static tryDecodeWellKnownSymbolName(name: ts.__String): string | undefined {
const match: RegExpExecArray | null = TypeScriptHelpers._wellKnownSymbolNameRegExp.exec(name as string);
if (match) {
const identifier: string = match[1];
return `[Symbol.${identifier}]`;
Expand All @@ -238,8 +238,8 @@ export class TypeScriptHelpers {
/**
* Returns whether the provided name was generated for a TypeScript `unique symbol`.
*/
public static isUniqueSymbolName(name: string): boolean {
return TypeScriptHelpers._uniqueSymbolNameRegExp.test(name);
public static isUniqueSymbolName(name: ts.__String): boolean {
return TypeScriptHelpers._uniqueSymbolNameRegExp.test(name as string);
}

/**
Expand Down
23 changes: 23 additions & 0 deletions src/generators/ApiModelGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,23 @@ import { Collector } from '../collector/Collector';
import { AstDeclaration } from '../analyzer/AstDeclaration';
import { ExcerptBuilder, IExcerptBuilderNodeToCapture } from './ExcerptBuilder';
import { AstSymbol } from '../analyzer/AstSymbol';
import { DeclarationReferenceGenerator } from './DeclarationReferenceGenerator';

export class ApiModelGenerator {
private readonly _collector: Collector;
private readonly _cachedOverloadIndexesByDeclaration: Map<AstDeclaration, number>;
private readonly _apiModel: ApiModel;
private readonly _referenceGenerator: DeclarationReferenceGenerator;

public constructor(collector: Collector) {
this._collector = collector;
this._cachedOverloadIndexesByDeclaration = new Map<AstDeclaration, number>();
this._apiModel = new ApiModel();
this._referenceGenerator = new DeclarationReferenceGenerator(
collector.packageJsonLookup,
collector.workingPackage.name,
collector.program,
collector.typeChecker);
}

public get apiModel(): ApiModel {
Expand Down Expand Up @@ -195,6 +202,7 @@ export class ApiModelGenerator {
const parameters: IApiParameterOptions[] = this._captureParameters(nodesToCapture, callSignature.parameters);

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
nodesToCapture
});
Expand Down Expand Up @@ -225,6 +233,7 @@ export class ApiModelGenerator {
constructorDeclaration.parameters);

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
nodesToCapture
});
Expand Down Expand Up @@ -274,6 +283,7 @@ export class ApiModelGenerator {
}

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
stopBeforeChildKind: ts.SyntaxKind.FirstPunctuation, // FirstPunctuation = "{"
nodesToCapture
Expand Down Expand Up @@ -314,6 +324,7 @@ export class ApiModelGenerator {
const parameters: IApiParameterOptions[] = this._captureParameters(nodesToCapture, constructSignature.parameters);

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
nodesToCapture
});
Expand All @@ -337,6 +348,7 @@ export class ApiModelGenerator {

if (apiEnum === undefined) {
const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
stopBeforeChildKind: ts.SyntaxKind.FirstPunctuation // FirstPunctuation = "{"
});
Expand Down Expand Up @@ -368,6 +380,7 @@ export class ApiModelGenerator {
nodesToCapture.push({ node: enumMember.initializer, tokenRange: initializerTokenRange });

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
nodesToCapture
});
Expand Down Expand Up @@ -408,6 +421,7 @@ export class ApiModelGenerator {
functionDeclaration.parameters);

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
nodesToCapture
});
Expand Down Expand Up @@ -441,6 +455,7 @@ export class ApiModelGenerator {
const parameters: IApiParameterOptions[] = this._captureParameters(nodesToCapture, indexSignature.parameters);

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
nodesToCapture
});
Expand Down Expand Up @@ -483,6 +498,7 @@ export class ApiModelGenerator {
}

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
stopBeforeChildKind: ts.SyntaxKind.FirstPunctuation, // FirstPunctuation = "{"
nodesToCapture
Expand Down Expand Up @@ -525,6 +541,7 @@ export class ApiModelGenerator {
const parameters: IApiParameterOptions[] = this._captureParameters(nodesToCapture, methodDeclaration.parameters);

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
nodesToCapture
});
Expand Down Expand Up @@ -564,6 +581,7 @@ export class ApiModelGenerator {
const parameters: IApiParameterOptions[] = this._captureParameters(nodesToCapture, methodSignature.parameters);

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
nodesToCapture
});
Expand All @@ -587,6 +605,7 @@ export class ApiModelGenerator {

if (apiNamespace === undefined) {
const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
stopBeforeChildKind: ts.SyntaxKind.ModuleBlock // ModuleBlock = the "{ ... }" block
});
Expand Down Expand Up @@ -622,6 +641,7 @@ export class ApiModelGenerator {
nodesToCapture.push({ node: propertyDeclaration.type, tokenRange: propertyTypeTokenRange });

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
nodesToCapture
});
Expand Down Expand Up @@ -654,6 +674,7 @@ export class ApiModelGenerator {
nodesToCapture.push({ node: propertySignature.type, tokenRange: propertyTypeTokenRange });

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
nodesToCapture
});
Expand Down Expand Up @@ -691,6 +712,7 @@ export class ApiModelGenerator {
nodesToCapture.push({ node: typeAliasDeclaration.type, tokenRange: typeTokenRange });

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
nodesToCapture
});
Expand Down Expand Up @@ -723,6 +745,7 @@ export class ApiModelGenerator {
nodesToCapture.push({ node: variableDeclaration.type, tokenRange: variableTypeTokenRange });

const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({
referenceGenerator: this._referenceGenerator,
startingNode: astDeclaration.declaration,
nodesToCapture
});
Expand Down
Loading

0 comments on commit 8af485a

Please sign in to comment.