From f1fa61f43fa666f96d27c31caaca1399a5dacc5d Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sat, 8 Jun 2019 17:44:50 -0700 Subject: [PATCH 1/8] Add support for emitting deeply linked types --- .../src/documenters/YamlDocumenter.ts | 328 ++++++++++++++---- apps/api-documenter/src/yaml/IYamlApiFile.ts | 11 + .../src/yaml/typescript.schema.json | 24 ++ .../src/items/ApiDeclaredItem.ts | 4 +- .../api-extractor-model/src/mixins/Excerpt.ts | 24 +- .../src/analyzer/AstSymbolTable.ts | 8 +- .../src/analyzer/TypeScriptHelpers.ts | 8 +- .../src/generators/ApiModelGenerator.ts | 23 ++ .../DeclarationReferenceGenerator.ts | 215 ++++++++++++ .../src/generators/ExcerptBuilder.ts | 73 +++- .../etc/api-documenter-test.api.json | 328 ++++++++++++++++-- .../etc/api-documenter-test.api.md | 16 + ...enter-test.idocinterface6.arrayproperty.md | 11 + ...t.idocinterface6.genericreferencemethod.md | 22 ++ ...est.idocinterface6.intersectionproperty.md | 11 + .../api-documenter-test.idocinterface6.md | 11 + ...enter-test.idocinterface6.tupleproperty.md | 11 + ...st.idocinterface6.typereferenceproperty.md | 11 + ...enter-test.idocinterface6.unionproperty.md | 11 + .../yaml/api-documenter-test/docclass1.yml | 9 + .../api-documenter-test/idocinterface1.yml | 3 + .../api-documenter-test/idocinterface2.yml | 3 + .../api-documenter-test/idocinterface4.yml | 47 ++- .../api-documenter-test/idocinterface6.yml | 145 ++++++++ .../api-documenter-test/src/DocClass1.ts | 13 + .../api-extractor-scenarios.api.json | 6 +- .../api-extractor-scenarios.api.json | 3 +- .../api-extractor-scenarios.api.json | 9 +- .../api-extractor-scenarios.api.json | 9 +- .../api-extractor-scenarios.api.json | 3 +- .../api-extractor-scenarios.api.json | 13 +- .../api-extractor-scenarios.api.json | 3 +- .../typeOf/api-extractor-scenarios.api.json | 6 +- .../api-extractor-scenarios.api.json | 6 +- .../deeplyLinkedTypes_2019-06-09-00-46.json | 11 + common/reviews/api/api-extractor-model.api.md | 12 +- 36 files changed, 1305 insertions(+), 146 deletions(-) create mode 100644 apps/api-extractor/src/generators/DeclarationReferenceGenerator.ts create mode 100644 build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.arrayproperty.md create mode 100644 build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.genericreferencemethod.md create mode 100644 build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.intersectionproperty.md create mode 100644 build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.tupleproperty.md create mode 100644 build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.typereferenceproperty.md create mode 100644 build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.unionproperty.md create mode 100644 common/changes/@microsoft/api-documenter/deeplyLinkedTypes_2019-06-09-00-46.json diff --git a/apps/api-documenter/src/documenters/YamlDocumenter.ts b/apps/api-documenter/src/documenters/YamlDocumenter.ts index 6b5844f38bb..b91183526e8 100644 --- a/apps/api-documenter/src/documenters/YamlDocumenter.ts +++ b/apps/api-documenter/src/documenters/YamlDocumenter.ts @@ -33,14 +33,23 @@ import { ApiConstructor, ApiFunction, ApiReturnTypeMixin, - ApiTypeParameterListMixin + ApiTypeParameterListMixin, + Excerpt, + ExcerptToken, + ExcerptTokenKind } from '@microsoft/api-extractor-model'; - +import { + DeclarationReference, + Navigation, + Meaning +} from '@microsoft/tsdoc/lib/beta/DeclarationReference'; import { IYamlApiFile, IYamlItem, IYamlSyntax, - IYamlParameter + IYamlParameter, + IYamlReference, + IYamlReferenceSpec } from '../yaml/IYamlApiFile'; import { IYamlTocFile, @@ -64,6 +73,9 @@ export class YamlDocumenter { // then it is excluded from the mapping. Also excluded are ApiItem objects (such as package // and function) which are not typically used as a data type. private _apiItemsByTypeName: Map; + private _knownTypeParameters: Set | undefined; + private _yamlReferences: IYamlReference[] | undefined; + private _uidTypeReferenceCounters: Map; private _outputFolder: string; @@ -71,6 +83,7 @@ export class YamlDocumenter { this._apiModel = apiModel; this._markdownEmitter = new CustomMarkdownEmitter(this._apiModel); this._apiItemsByTypeName = new Map(); + this._uidTypeReferenceCounters = new Map(); this._initApiItemsByTypeName(); } @@ -105,67 +118,94 @@ export class YamlDocumenter { } private _visitApiItems(apiItem: ApiDocumentedItem, parentYamlFile: IYamlApiFile | undefined): boolean { - const yamlItem: IYamlItem | undefined = this._generateYamlItem(apiItem); - if (!yamlItem) { - return false; - } - - this.onCustomizeYamlItem(yamlItem); + const savedKnownTypeParameters: Set | undefined = this._knownTypeParameters; + try { + // Track type parameters declared by a declaration so that we do not resolve them + // when looking up types in _linkToUidIfPossible() + if (ApiTypeParameterListMixin.isBaseClassOf(apiItem)) { + this._knownTypeParameters = savedKnownTypeParameters + ? new Set(savedKnownTypeParameters) + : new Set(); + for (const typeParameter of apiItem.typeParameters) { + this._knownTypeParameters.add(typeParameter.name); + } + } - if (this._shouldEmbed(apiItem.kind)) { - if (!parentYamlFile) { - throw new InternalError('Missing file context'); + const yamlItem: IYamlItem | undefined = this._generateYamlItem(apiItem); + if (!yamlItem) { + return false; } - parentYamlFile.items.push(yamlItem); - } else { - const newYamlFile: IYamlApiFile = { - items: [] - }; - newYamlFile.items.push(yamlItem); - let children: ReadonlyArray; - if (apiItem.kind === ApiItemKind.Package) { - // Skip over the entry point, since it's not part of the documentation hierarchy - children = apiItem.members[0].members; + this.onCustomizeYamlItem(yamlItem); + + if (this._shouldEmbed(apiItem.kind)) { + if (!parentYamlFile) { + throw new InternalError('Missing file context'); + } + parentYamlFile.items.push(yamlItem); } else { - children = apiItem.members; - } + const newYamlFile: IYamlApiFile = { + items: [] + }; + newYamlFile.items.push(yamlItem); + + let children: ReadonlyArray; + if (apiItem.kind === ApiItemKind.Package) { + // Skip over the entry point, since it's not part of the documentation hierarchy + children = apiItem.members[0].members; + } else { + children = apiItem.members; + } - const flattenedChildren: ApiItem[] = this._flattenNamespaces(children); + const flattenedChildren: ApiItem[] = this._flattenNamespaces(children); - for (const child of flattenedChildren) { - if (child instanceof ApiDocumentedItem) { - if (this._visitApiItems(child, newYamlFile)) { - if (!yamlItem.children) { - yamlItem.children = []; + for (const child of flattenedChildren) { + if (child instanceof ApiDocumentedItem) { + if (this._visitApiItems(child, newYamlFile)) { + if (!yamlItem.children) { + yamlItem.children = []; + } + yamlItem.children.push(this._getUid(child)); } - yamlItem.children.push(this._getUid(child)); } } - } - - const yamlFilePath: string = this._getYamlFilePath(apiItem); - if (apiItem.kind === ApiItemKind.Package) { - console.log('Writing ' + yamlFilePath); - } + if (this._yamlReferences) { + if (this._yamlReferences.length > 0) { + if (newYamlFile.references) { + newYamlFile.references = [...newYamlFile.references, ...this._yamlReferences]; + } else { + newYamlFile.references = this._yamlReferences; + } + } + this._yamlReferences = undefined; + } - this._writeYamlFile(newYamlFile, yamlFilePath, 'UniversalReference', yamlApiSchema); + const yamlFilePath: string = this._getYamlFilePath(apiItem); - if (parentYamlFile) { - if (!parentYamlFile.references) { - parentYamlFile.references = []; + if (apiItem.kind === ApiItemKind.Package) { + console.log('Writing ' + yamlFilePath); } - parentYamlFile.references.push({ - uid: this._getUid(apiItem), - name: this._getYamlItemName(apiItem) - }); + this._writeYamlFile(newYamlFile, yamlFilePath, 'UniversalReference', yamlApiSchema); + + if (parentYamlFile) { + if (!parentYamlFile.references) { + parentYamlFile.references = []; + } + parentYamlFile.references.push({ + uid: this._getUid(apiItem), + name: this._getYamlItemName(apiItem) + }); + + } } - } - return true; + return true; + } finally { + this._knownTypeParameters = savedKnownTypeParameters; + } } // Since the YAML schema does not yet support nested namespaces, we simply omit them from @@ -275,8 +315,10 @@ export class YamlDocumenter { return undefined; } - const yamlItem: Partial = { }; - yamlItem.uid = this._getUid(apiItem); + const uid: DeclarationReference = this._getUidObject(apiItem); + const yamlItem: Partial = { + uid: uid.toString() + }; if (apiItem.tsdocComment) { const tsdocComment: DocComment = apiItem.tsdocComment; @@ -328,21 +370,21 @@ export class YamlDocumenter { break; case ApiItemKind.Class: yamlItem.type = 'class'; - this._populateYamlClassOrInterface(yamlItem, apiItem as ApiClass); + this._populateYamlClassOrInterface(uid, yamlItem, apiItem as ApiClass); break; case ApiItemKind.Interface: yamlItem.type = 'interface'; - this._populateYamlClassOrInterface(yamlItem, apiItem as ApiInterface); + this._populateYamlClassOrInterface(uid, yamlItem, apiItem as ApiInterface); break; case ApiItemKind.Method: case ApiItemKind.MethodSignature: yamlItem.type = 'method'; - this._populateYamlFunctionLike(yamlItem, apiItem as ApiMethod | ApiMethodSignature); + this._populateYamlFunctionLike(uid, yamlItem, apiItem as ApiMethod | ApiMethodSignature); break; case ApiItemKind.Constructor: yamlItem.type = 'constructor'; - this._populateYamlFunctionLike(yamlItem, apiItem as ApiConstructor); + this._populateYamlFunctionLike(uid, yamlItem, apiItem as ApiConstructor); break; case ApiItemKind.Package: @@ -356,12 +398,12 @@ export class YamlDocumenter { } else { yamlItem.type = 'property'; } - this._populateYamlProperty(yamlItem, apiProperty); + this._populateYamlProperty(uid, yamlItem, apiProperty); break; case ApiItemKind.Function: yamlItem.type = 'function'; - this._populateYamlFunctionLike(yamlItem, apiItem as ApiFunction); + this._populateYamlFunctionLike(uid, yamlItem, apiItem as ApiFunction); break; default: @@ -379,7 +421,9 @@ export class YamlDocumenter { return yamlItem as IYamlItem; } - private _populateYamlTypeParameters(apiItem: ApiTypeParameterListMixin): IYamlParameter[] { + private _populateYamlTypeParameters(contextUid: DeclarationReference, apiItem: ApiTypeParameterListMixin): + IYamlParameter[] { + const typeParameters: IYamlParameter[] = []; for (const apiTypeParameter of apiItem.typeParameters) { const typeParameter: IYamlParameter = { @@ -391,7 +435,7 @@ export class YamlDocumenter { } if (!apiTypeParameter.constraintExcerpt.isEmpty) { - typeParameter.type = [ this._linkToUidIfPossible(apiTypeParameter.constraintExcerpt.text) ]; + typeParameter.type = [ this._renderType(contextUid, apiTypeParameter.constraintExcerpt) ]; } typeParameters.push(typeParameter); @@ -399,26 +443,28 @@ export class YamlDocumenter { return typeParameters; } - private _populateYamlClassOrInterface(yamlItem: Partial, apiItem: ApiClass | ApiInterface): void { + private _populateYamlClassOrInterface(uid: DeclarationReference, yamlItem: Partial, apiItem: ApiClass | + ApiInterface): void { + if (apiItem instanceof ApiClass) { if (apiItem.extendsType) { - yamlItem.extends = [ this._linkToUidIfPossible(apiItem.extendsType.excerpt.text) ]; + yamlItem.extends = [ this._renderType(uid, apiItem.extendsType.excerpt) ]; } if (apiItem.implementsTypes.length > 0) { yamlItem.implements = []; for (const implementsType of apiItem.implementsTypes) { - yamlItem.implements.push(this._linkToUidIfPossible(implementsType.excerpt.text)); + yamlItem.implements.push(this._renderType(uid, implementsType.excerpt)); } } } else if (apiItem instanceof ApiInterface) { if (apiItem.extendsTypes.length > 0) { yamlItem.extends = []; for (const extendsType of apiItem.extendsTypes) { - yamlItem.extends.push(this._linkToUidIfPossible(extendsType.excerpt.text)); + yamlItem.extends.push(this._renderType(uid, extendsType.excerpt)); } } - const typeParameters: IYamlParameter[] = this._populateYamlTypeParameters(apiItem); + const typeParameters: IYamlParameter[] = this._populateYamlTypeParameters(uid, apiItem); if (typeParameters.length) { yamlItem.syntax = { typeParameters }; } @@ -441,8 +487,8 @@ export class YamlDocumenter { } } - private _populateYamlFunctionLike(yamlItem: Partial, apiItem: ApiMethod | ApiMethodSignature - | ApiConstructor | ApiFunction): void { + private _populateYamlFunctionLike(uid: DeclarationReference, yamlItem: Partial, apiItem: ApiMethod | + ApiMethodSignature | ApiConstructor | ApiFunction): void { const syntax: IYamlSyntax = { content: apiItem.getExcerptWithModifiers() @@ -450,7 +496,7 @@ export class YamlDocumenter { yamlItem.syntax = syntax; if (ApiReturnTypeMixin.isBaseClassOf(apiItem)) { - const returnType: string = this._linkToUidIfPossible(apiItem.returnTypeExcerpt.text); + const returnType: string = this._renderType(uid, apiItem.returnTypeExcerpt); let returnDescription: string = ''; @@ -479,7 +525,7 @@ export class YamlDocumenter { { id: apiParameter.name, description: parameterDescription, - type: [ this._linkToUidIfPossible(apiParameter.parameterTypeExcerpt.text) ] + type: [ this._renderType(uid, apiParameter.parameterTypeExcerpt) ] } as IYamlParameter ); } @@ -489,7 +535,7 @@ export class YamlDocumenter { } if (ApiTypeParameterListMixin.isBaseClassOf(apiItem)) { - const typeParameters: IYamlParameter[] = this._populateYamlTypeParameters(apiItem); + const typeParameters: IYamlParameter[] = this._populateYamlTypeParameters(uid, apiItem); if (typeParameters.length) { syntax.typeParameters = typeParameters; } @@ -497,7 +543,9 @@ export class YamlDocumenter { } - private _populateYamlProperty(yamlItem: Partial, apiItem: ApiPropertyItem): void { + private _populateYamlProperty(uid: DeclarationReference, yamlItem: Partial, apiItem: ApiPropertyItem): + void { + const syntax: IYamlSyntax = { content: apiItem.getExcerptWithModifiers() }; @@ -505,7 +553,7 @@ export class YamlDocumenter { if (apiItem.propertyTypeExcerpt.text) { syntax.return = { - type: [ this._linkToUidIfPossible(apiItem.propertyTypeExcerpt.text) ] + type: [ this._renderType(uid, apiItem.propertyTypeExcerpt) ] }; } } @@ -553,7 +601,11 @@ export class YamlDocumenter { * Example: `node-core-library!JsonFile#load` */ protected _getUid(apiItem: ApiItem): string { - return apiItem.canonicalReference.toString(); + return this._getUidObject(apiItem).toString(); + } + + protected _getUidObject(apiItem: ApiItem): DeclarationReference { + return apiItem.canonicalReference; } /** @@ -615,6 +667,13 @@ export class YamlDocumenter { } } + private _ensureYamlReferences(): IYamlReference[] { + if (!this._yamlReferences) { + this._yamlReferences = []; + } + return this._yamlReferences; + } + /** * This is a temporary workaround to enable limited autolinking of API item types * until the YAML file format is enhanced to support general hyperlinks. @@ -625,14 +684,131 @@ export class YamlDocumenter { * contain any Markdown links. The _substituteUidForSimpleType() function assumes * it is given #2 but substitutes #1 if the name can be matched to a ApiItem. */ - private _linkToUidIfPossible(typeName: string): string { + private _linkToUidIfPossible(typeName: string): string | undefined { + typeName = typeName.trim(); + // Do not look up the UID for a type parameter, as we could inadvertently + // look up a different type with the same name. + if (this._knownTypeParameters && this._knownTypeParameters.has(typeName)) { + return typeName; + } + // Note that typeName might be a _getTypeNameWithDot() name or it might be a simple class name - const apiItem: ApiItem | undefined = this._apiItemsByTypeName.get(typeName.trim()); + const apiItem: ApiItem | undefined = this._apiItemsByTypeName.get(typeName); if (apiItem) { // Substitute the UID return this._getUid(apiItem); } - return typeName; + } + + private _renderType(contextUid: DeclarationReference, typeExcerpt: Excerpt): string { + const excerptTokens: ExcerptToken[] = typeExcerpt.tokens.slice( + typeExcerpt.tokenRange.startIndex, + typeExcerpt.tokenRange.endIndex); + + if (excerptTokens.length === 0) { + return ''; + } + + // Remove the last token if it consists only of whitespace + const lastToken: ExcerptToken = excerptTokens[excerptTokens.length - 1]; + if (lastToken.kind === ExcerptTokenKind.Content && !lastToken.text.trim()) { + excerptTokens.pop(); + if (excerptTokens.length === 0) { + return ''; + } + } + + const typeName: string = typeExcerpt.text.trim(); + if (excerptTokens.length === 1 && + excerptTokens[0].kind === ExcerptTokenKind.Reference && + excerptTokens[0].canonicalReference) { + return this._recordYamlReference( + excerptTokens[0].canonicalReference.toString(), + typeName + ); + } + + const typeNameAsUid: string | undefined = this._linkToUidIfPossible(typeName); + if (typeNameAsUid !== undefined) { + if (typeNameAsUid !== typeName) { + return this._recordYamlReference(typeNameAsUid, typeName); + } + return typeNameAsUid; + } + + if (isEntityName(typeName)) { + return typeName; + } + + // If there are no references to be used for a complex type, return the type name. + if (!excerptTokens.some(tok => tok.kind === ExcerptTokenKind.Reference)) { + return typeName; + } + + const baseUid: string = contextUid + .withMeaning(undefined) + .withOverloadIndex(undefined) + .toString(); + const counter: number = this._uidTypeReferenceCounters.get(baseUid) || 0; + const uid: string = contextUid + .addNavigationStep(Navigation.Locals, `${counter}`) + .withMeaning(Meaning.ComplexType) + .toString(); + this._uidTypeReferenceCounters.set(baseUid, counter + 1); + this._recordYamlReference(uid, typeName, excerptTokens); + return uid; + } + + private _recordYamlReference(uid: string, typeName: string, excerptTokens?: ExcerptToken[]): string { + const yamlReferences: IYamlReference[] = this._ensureYamlReferences(); + + if (yamlReferences.some(ref => ref.uid === uid)) { + return uid; + } + + // Fill in the reference spec from the excerpt. + const spec: IYamlReferenceSpec[] = []; + if (excerptTokens) { + for (const token of excerptTokens) { + if (token.kind === ExcerptTokenKind.Reference) { + let specUid: string | undefined = token.canonicalReference && token.canonicalReference.toString(); + const apiItem: ApiItem | undefined = this._apiItemsByTypeName.get(token.text); + if (specUid === undefined) { + if (apiItem) { + specUid = this._getUid(apiItem); + } else { + specUid = token.text; + } + } + spec.push( + { + uid: specUid, + name: token.text, + fullName: apiItem ? apiItem.getScopedNameWithinPackage() : token.text + } + ); + } else { + spec.push( + { + name: token.text, + fullName: token.text + } + ); + } + } + } + + const yamlReference: IYamlReference = { uid }; + if (spec.length > 0) { + yamlReference.name = spec.map(s => s.name).join('').trim(); + yamlReference.fullName = spec.map(s => s.fullName || s.name).join('').trim(); + yamlReference['spec.typeScript'] = spec; + } else if (typeName !== uid) { + yamlReference.name = typeName; + } + + yamlReferences.push(yamlReference); + return uid; } /** @@ -721,3 +897,9 @@ export class YamlDocumenter { FileSystem.ensureEmptyFolder(this._outputFolder); } } + +const entityNameRegExp: RegExp = /^(?!\d)[\w$_]+(\.(?!\d)[\w$_]+)*$/; + +function isEntityName(text: string): boolean { + return entityNameRegExp.test(text); +} \ No newline at end of file diff --git a/apps/api-documenter/src/yaml/IYamlApiFile.ts b/apps/api-documenter/src/yaml/IYamlApiFile.ts index 450a565a42e..3eb0d7cf5ee 100644 --- a/apps/api-documenter/src/yaml/IYamlApiFile.ts +++ b/apps/api-documenter/src/yaml/IYamlApiFile.ts @@ -73,8 +73,19 @@ export interface IYamlParameter { * declared in a separate YAML file. */ export interface IYamlReference { + uid?: string; name?: string; + fullName?: string; + 'spec.typeScript'?: IYamlReferenceSpec[]; +} + +/** + * Part of the IYamlApiFile structure. Represents a text specification for a reference. + */ +export interface IYamlReferenceSpec { uid?: string; + name?: string; + fullName?: string; } /** diff --git a/apps/api-documenter/src/yaml/typescript.schema.json b/apps/api-documenter/src/yaml/typescript.schema.json index c67b8f3c813..b10570c3a70 100644 --- a/apps/api-documenter/src/yaml/typescript.schema.json +++ b/apps/api-documenter/src/yaml/typescript.schema.json @@ -159,11 +159,35 @@ "type": "object", "additionalProperties": false, "properties": { + "uid": { + "type": "string" + }, "name": { "type": "string" }, + "fullName": { + "type": "string" + }, + "spec.typeScript": { + "type": "array", + "items": { + "$ref": "#/definitions/spec" + } + } + } + }, + "spec": { + "type": "object", + "additionalProperties": false, + "properties": { "uid": { "type": "string" + }, + "name": { + "type": "string" + }, + "fullName": { + "type": "string" } } }, diff --git a/apps/api-extractor-model/src/items/ApiDeclaredItem.ts b/apps/api-extractor-model/src/items/ApiDeclaredItem.ts index 57b6e2be1b9..6abefe7f1db 100644 --- a/apps/api-extractor-model/src/items/ApiDeclaredItem.ts +++ b/apps/api-extractor-model/src/items/ApiDeclaredItem.ts @@ -47,7 +47,7 @@ export class ApiDeclaredItem extends ApiDocumentedItem { public constructor(options: IApiDeclaredItemOptions) { super(options); - this._excerptTokens = options.excerptTokens.map(x => new ExcerptToken(x.kind, x.text)); + this._excerptTokens = options.excerptTokens.map(x => ExcerptToken.fromJSON(x)); this._excerpt = new Excerpt(this.excerptTokens, { startIndex: 0, endIndex: this.excerptTokens.length }); } @@ -99,7 +99,7 @@ export class ApiDeclaredItem extends ApiDocumentedItem { /** @override */ public serializeInto(jsonObject: Partial): void { super.serializeInto(jsonObject); - jsonObject.excerptTokens = this.excerptTokens.map(x => ({ kind: x.kind, text: x.text })); + jsonObject.excerptTokens = this.excerptTokens.map(x => x.toJSON()); } /** diff --git a/apps/api-extractor-model/src/mixins/Excerpt.ts b/apps/api-extractor-model/src/mixins/Excerpt.ts index fd2e76036ca..a5f5bce4a2b 100644 --- a/apps/api-extractor-model/src/mixins/Excerpt.ts +++ b/apps/api-extractor-model/src/mixins/Excerpt.ts @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. +import { DeclarationReference } from '@microsoft/tsdoc/lib/beta/DeclarationReference'; import { Text } from '@microsoft/node-core-library'; /** @public */ @@ -21,20 +22,23 @@ export interface IExcerptTokenRange { export interface IExcerptToken { readonly kind: ExcerptTokenKind; text: string; + canonicalReference?: string; } /** @public */ export class ExcerptToken { private readonly _kind: ExcerptTokenKind; private readonly _text: string; + private readonly _canonicalReference: DeclarationReference | undefined; - public constructor(kind: ExcerptTokenKind, text: string) { + public constructor(kind: ExcerptTokenKind, text: string, canonicalReference?: DeclarationReference) { this._kind = kind; // Standardize the newlines across operating systems. Even though this may deviate from the actual // input source file that was parsed, it's useful because the newline gets serialized inside // a string literal in .api.json, which cannot be automatically normalized by Git. this._text = Text.convertToLf(text); + this._canonicalReference = canonicalReference; } public get kind(): ExcerptTokenKind { @@ -44,6 +48,24 @@ export class ExcerptToken { public get text(): string { return this._text; } + + public get canonicalReference(): DeclarationReference | undefined { + return this._canonicalReference; + } + + public static fromJSON(object: IExcerptToken): ExcerptToken { + const canonicalReference: DeclarationReference | undefined = object.canonicalReference === undefined ? undefined : + DeclarationReference.parse(object.canonicalReference); + return new ExcerptToken(object.kind, object.text, canonicalReference); + } + + public toJSON(): IExcerptToken { + const excerptToken: IExcerptToken = { kind: this.kind, text: this.text }; + if (this._canonicalReference !== undefined) { + excerptToken.canonicalReference = this._canonicalReference.toString(); + } + return excerptToken; + } } /** diff --git a/apps/api-extractor/src/analyzer/AstSymbolTable.ts b/apps/api-extractor/src/analyzer/AstSymbolTable.ts index 8a83c5cfd65..07670a884c2 100644 --- a/apps/api-extractor/src/analyzer/AstSymbolTable.ts +++ b/apps/api-extractor/src/analyzer/AstSymbolTable.ts @@ -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" diff --git a/apps/api-extractor/src/analyzer/TypeScriptHelpers.ts b/apps/api-extractor/src/analyzer/TypeScriptHelpers.ts index 91a27a7dea8..c233dfa5cb7 100644 --- a/apps/api-extractor/src/analyzer/TypeScriptHelpers.ts +++ b/apps/api-extractor/src/analyzer/TypeScriptHelpers.ts @@ -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}]`; @@ -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); } /** diff --git a/apps/api-extractor/src/generators/ApiModelGenerator.ts b/apps/api-extractor/src/generators/ApiModelGenerator.ts index 6a8d4ea8713..d29a6d60f4d 100644 --- a/apps/api-extractor/src/generators/ApiModelGenerator.ts +++ b/apps/api-extractor/src/generators/ApiModelGenerator.ts @@ -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; private readonly _apiModel: ApiModel; + private readonly _referenceGenerator: DeclarationReferenceGenerator; public constructor(collector: Collector) { this._collector = collector; this._cachedOverloadIndexesByDeclaration = new Map(); this._apiModel = new ApiModel(); + this._referenceGenerator = new DeclarationReferenceGenerator( + collector.packageJsonLookup, + collector.workingPackage.name, + collector.program, + collector.typeChecker); } public get apiModel(): ApiModel { @@ -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 }); @@ -225,6 +233,7 @@ export class ApiModelGenerator { constructorDeclaration.parameters); const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({ + referenceGenerator: this._referenceGenerator, startingNode: astDeclaration.declaration, nodesToCapture }); @@ -274,6 +283,7 @@ export class ApiModelGenerator { } const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({ + referenceGenerator: this._referenceGenerator, startingNode: astDeclaration.declaration, stopBeforeChildKind: ts.SyntaxKind.FirstPunctuation, // FirstPunctuation = "{" nodesToCapture @@ -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 }); @@ -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 = "{" }); @@ -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 }); @@ -408,6 +421,7 @@ export class ApiModelGenerator { functionDeclaration.parameters); const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({ + referenceGenerator: this._referenceGenerator, startingNode: astDeclaration.declaration, nodesToCapture }); @@ -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 }); @@ -483,6 +498,7 @@ export class ApiModelGenerator { } const excerptTokens: IExcerptToken[] = ExcerptBuilder.build({ + referenceGenerator: this._referenceGenerator, startingNode: astDeclaration.declaration, stopBeforeChildKind: ts.SyntaxKind.FirstPunctuation, // FirstPunctuation = "{" nodesToCapture @@ -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 }); @@ -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 }); @@ -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 }); @@ -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 }); @@ -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 }); @@ -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 }); @@ -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 }); diff --git a/apps/api-extractor/src/generators/DeclarationReferenceGenerator.ts b/apps/api-extractor/src/generators/DeclarationReferenceGenerator.ts new file mode 100644 index 00000000000..707ef3550a2 --- /dev/null +++ b/apps/api-extractor/src/generators/DeclarationReferenceGenerator.ts @@ -0,0 +1,215 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +// tslint:disable:no-bitwise +import * as ts from 'typescript'; +import { + DeclarationReference, + ModuleSource, + GlobalSource, + Navigation, + Meaning +} from '@microsoft/tsdoc/lib/beta/DeclarationReference'; +import { PackageJsonLookup, INodePackageJson, InternalError } from '@microsoft/node-core-library'; +import { TypeScriptHelpers } from '../analyzer/TypeScriptHelpers'; +import { TypeScriptInternals } from '../analyzer/TypeScriptInternals'; + +export class DeclarationReferenceGenerator { + public static readonly unknownReference: string = '?'; + + private _packageJsonLookup: PackageJsonLookup; + private _workingPackageName: string; + private _program: ts.Program; + private _typeChecker: ts.TypeChecker; + + constructor(packageJsonLookup: PackageJsonLookup, workingPackageName: string, program: ts.Program, + typeChecker: ts.TypeChecker) { + + this._packageJsonLookup = packageJsonLookup; + this._workingPackageName = workingPackageName; + this._program = program; + this._typeChecker = typeChecker; + } + + /** + * Gets the UID for a TypeScript Identifier that references a type. + */ + public getDeclarationReferenceForIdentifier(node: ts.Identifier): DeclarationReference | undefined { + const symbol: ts.Symbol | undefined = this._typeChecker.getSymbolAtLocation(node); + if (symbol !== undefined) { + const isExpression: boolean = isInExpressionContext(node); + return this.getDeclarationReferenceForSymbol(symbol, isExpression ? ts.SymbolFlags.Value : ts.SymbolFlags.Type) + || this.getDeclarationReferenceForSymbol(symbol, isExpression ? ts.SymbolFlags.Type : ts.SymbolFlags.Value) + || this.getDeclarationReferenceForSymbol(symbol, ts.SymbolFlags.Namespace); + } + } + + /** + * Gets the DeclarationReference for a TypeScript Symbol for a given meaning. + */ + public getDeclarationReferenceForSymbol(symbol: ts.Symbol, meaning: ts.SymbolFlags + ): DeclarationReference | undefined { + return this._symbolToDeclarationReference(symbol, meaning, /*includeModuleSymbols*/ false); + } + + private _symbolToDeclarationReference(symbol: ts.Symbol, meaning: ts.SymbolFlags, includeModuleSymbols: boolean + ): DeclarationReference | undefined { + if (symbol.flags & ts.SymbolFlags.ExportValue) { + symbol = this._typeChecker.getExportSymbolOfSymbol(symbol); + } + if (symbol.flags & ts.SymbolFlags.Alias) { + symbol = this._typeChecker.getAliasedSymbol(symbol); + } + + if (isExternalModuleSymbol(symbol)) { + if (!includeModuleSymbols) { + return undefined; + } + const sourceFile: ts.SourceFile | undefined = + symbol.declarations + && symbol.declarations[0] + && symbol.declarations[0].getSourceFile(); + return new DeclarationReference(this._sourceFileToModuleSource(sourceFile)); + } + + if (symbol.flags & ts.SymbolFlags.TypeParameter) { + return DeclarationReference.parse(DeclarationReference.escapeComponentString(symbol.name)); + } + + const parent: ts.Symbol | undefined = TypeScriptInternals.getSymbolParent(symbol); + const parentRef: DeclarationReference | undefined = parent + ? this._symbolToDeclarationReference(parent, ts.SymbolFlags.Namespace, /*includeModuleSymbols*/ true) + : new DeclarationReference(GlobalSource.instance); + + if (parentRef === undefined) { + return undefined; + } + + let localName: string = symbol.name; + if (symbol.escapedName === ts.InternalSymbolName.Constructor) { + localName = 'constructor'; + } else { + const wellKnownName: string | undefined = TypeScriptHelpers.tryDecodeWellKnownSymbolName(symbol.escapedName); + if (wellKnownName) { + // TypeScript binds well-known ECMAScript symbols like 'Symbol.iterator' as '__@iterator'. + // This converts a string like '__@iterator' into the property name '[Symbol.iterator]'. + localName = wellKnownName; + } else if (TypeScriptHelpers.isUniqueSymbolName(symbol.escapedName)) { + for (const decl of symbol.declarations || []) { + const declName: ts.DeclarationName | undefined = ts.getNameOfDeclaration(decl); + if (declName && ts.isComputedPropertyName(declName)) { + const lateName: string | undefined = TypeScriptHelpers.tryGetLateBoundName(declName); + if (lateName !== undefined) { + localName = lateName; + break; + } + } + } + } + } + + const navigation: Navigation = isTypeMemberOrNonStaticClassMember(symbol) + ? Navigation.Members + : Navigation.Exports; + + return parentRef + .addNavigationStep(navigation, localName) + .withMeaning(getMeaningOfSymbol(symbol, meaning)); + } + + private _getPackageName(sourceFile: ts.SourceFile): string { + if (this._program.isSourceFileFromExternalLibrary(sourceFile)) { + const packageJson: INodePackageJson | undefined = this._packageJsonLookup + .tryLoadNodePackageJsonFor(sourceFile.fileName); + + if (packageJson && packageJson.name) { + return packageJson.name; + } + return DeclarationReferenceGenerator.unknownReference; + } + return this._workingPackageName; + } + + private _sourceFileToModuleSource(sourceFile: ts.SourceFile | undefined): GlobalSource | ModuleSource { + if (sourceFile && ts.isExternalModule(sourceFile)) { + return new ModuleSource(this._getPackageName(sourceFile)); + } + return GlobalSource.instance; + } +} + +function isExternalModuleSymbol(symbol: ts.Symbol): boolean { + return !!(symbol.flags & ts.SymbolFlags.ValueModule) + && symbol.valueDeclaration !== undefined + && ts.isSourceFile(symbol.valueDeclaration); +} + +function isTypeMemberOrNonStaticClassMember(symbol: ts.Symbol): boolean { + if (symbol.valueDeclaration) { + if (ts.isClassLike(symbol.valueDeclaration.parent)) { + return ts.isClassElement(symbol.valueDeclaration) + && !(ts.getCombinedModifierFlags(symbol.valueDeclaration) & ts.ModifierFlags.Static); + } + if (ts.isInterfaceDeclaration(symbol.valueDeclaration.parent)) { + return ts.isTypeElement(symbol.valueDeclaration); + } + } + return false; +} + +function getMeaningOfSymbol(symbol: ts.Symbol, meaning: ts.SymbolFlags): Meaning | undefined { + if (symbol.flags & meaning & ts.SymbolFlags.Class) { + return Meaning.Class; + } + if (symbol.flags & meaning & ts.SymbolFlags.Enum) { + return Meaning.Enum; + } + if (symbol.flags & meaning & ts.SymbolFlags.Interface) { + return Meaning.Interface; + } + if (symbol.flags & meaning & ts.SymbolFlags.TypeAlias) { + return Meaning.TypeAlias; + } + if (symbol.flags & meaning & ts.SymbolFlags.Function) { + return Meaning.Function; + } + if (symbol.flags & meaning & ts.SymbolFlags.Variable) { + return Meaning.Variable; + } + if (symbol.flags & meaning & ts.SymbolFlags.Module) { + return Meaning.Namespace; + } + if (symbol.flags & meaning & ts.SymbolFlags.ClassMember) { + return Meaning.Member; + } + if (symbol.flags & meaning & ts.SymbolFlags.Constructor) { + return Meaning.Constructor; + } + if (symbol.flags & meaning & ts.SymbolFlags.EnumMember) { + return Meaning.Member; + } + if (symbol.flags & meaning & ts.SymbolFlags.Signature) { + if (symbol.escapedName === ts.InternalSymbolName.Call) { + return Meaning.CallSignature; + } + if (symbol.escapedName === ts.InternalSymbolName.New) { + return Meaning.ConstructSignature; + } + if (symbol.escapedName === ts.InternalSymbolName.Index) { + return Meaning.IndexSignature; + } + } + if (symbol.flags & meaning & ts.SymbolFlags.TypeParameter) { + // This should have already been handled in `getDeclarationReferenceOfSymbol`. + throw new InternalError('Not supported.'); + } + return undefined; +} + +function isInExpressionContext(node: ts.Node): boolean { + switch (node.parent.kind) { + case ts.SyntaxKind.TypeQuery: return true; + case ts.SyntaxKind.QualifiedName: return isInExpressionContext(node.parent); + default: return false; + } +} \ No newline at end of file diff --git a/apps/api-extractor/src/generators/ExcerptBuilder.ts b/apps/api-extractor/src/generators/ExcerptBuilder.ts index de97f8b6077..ce71e902a8f 100644 --- a/apps/api-extractor/src/generators/ExcerptBuilder.ts +++ b/apps/api-extractor/src/generators/ExcerptBuilder.ts @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. import * as ts from 'typescript'; +import { DeclarationReference } from '@microsoft/tsdoc/lib/beta/DeclarationReference'; import { ExcerptTokenKind, IExcerptToken, @@ -9,6 +10,7 @@ import { } from '@microsoft/api-extractor-model'; import { Span } from '../analyzer/Span'; +import { DeclarationReferenceGenerator } from './DeclarationReferenceGenerator'; /** * Used to provide ExcerptBuilder with a list of nodes whose token range we want to capture. @@ -29,6 +31,7 @@ export interface IExcerptBuilderNodeToCapture { * Options for ExcerptBuilder */ export interface ISignatureBuilderOptions { + referenceGenerator: DeclarationReferenceGenerator; /** * The AST node that we will traverse to extract tokens */ @@ -55,6 +58,7 @@ export interface ISignatureBuilderOptions { * Internal state for ExcerptBuilder */ interface IBuildSpanState { + referenceGenerator: DeclarationReferenceGenerator; startingNode: ts.Node; stopBeforeChildKind: ts.SyntaxKind | undefined; @@ -82,6 +86,7 @@ export class ExcerptBuilder { const excerptTokens: IExcerptToken[] = []; ExcerptBuilder._buildSpan(excerptTokens, span, { + referenceGenerator: options.referenceGenerator, startingNode: options.startingNode, stopBeforeChildKind: options.stopBeforeChildKind, tokenRangesByNode, @@ -113,8 +118,12 @@ export class ExcerptBuilder { if (span.prefix) { if (span.kind === ts.SyntaxKind.Identifier) { + const name: ts.Identifier = span.node as ts.Identifier; + const canonicalReference: DeclarationReference | undefined = isDeclarationName(name) + ? undefined + : state.referenceGenerator.getDeclarationReferenceForIdentifier(name); ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Reference, - span.prefix, state); + span.prefix, state, canonicalReference); } else { ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Content, span.prefix, state); @@ -155,16 +164,31 @@ export class ExcerptBuilder { } private static _appendToken(excerptTokens: IExcerptToken[], excerptTokenKind: ExcerptTokenKind, - text: string, state: IBuildSpanState): void { + text: string, state: IBuildSpanState, canonicalReference?: DeclarationReference): void { if (text.length === 0) { return; } if (excerptTokenKind !== ExcerptTokenKind.Content) { - excerptTokens.push({ kind: excerptTokenKind, text: text}); - state.disableMergingForNextToken = false; - + if (excerptTokenKind === ExcerptTokenKind.Reference && excerptTokens.length > 1 + && !state.disableMergingForNextToken) { + // If the previous two tokens were a Reference and a '.', then concatenate + // all three tokens as a qualified name Reference. + const previousTokenM1: IExcerptToken = excerptTokens[excerptTokens.length - 1]; + const previousTokenM2: IExcerptToken = excerptTokens[excerptTokens.length - 2]; + if (previousTokenM1.kind === ExcerptTokenKind.Content + && previousTokenM1.text.trim() === '.' + && previousTokenM2.kind === ExcerptTokenKind.Reference) { + + previousTokenM2.text += '.' + text; + if (canonicalReference !== undefined) { + previousTokenM2.canonicalReference = canonicalReference.toString(); + } + excerptTokens.pop(); // remove previousTokenM1; + return; + } + } } else { // If someone referenced this index, then we need to start a new token if (excerptTokens.length > 0 && !state.disableMergingForNextToken) { @@ -175,10 +199,45 @@ export class ExcerptBuilder { return; } } + } - excerptTokens.push({ kind: excerptTokenKind, text: text}); - state.disableMergingForNextToken = false; + const excerptToken: IExcerptToken = { kind: excerptTokenKind, text: text }; + if (canonicalReference !== undefined) { + excerptToken.canonicalReference = canonicalReference.toString(); } + excerptTokens.push(excerptToken); + state.disableMergingForNextToken = false; } } + +function isDeclaration(node: ts.Node): node is ts.NamedDeclaration { + switch (node.kind) { + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.TypeParameter: + case ts.SyntaxKind.EnumMember: + case ts.SyntaxKind.BindingElement: + return true; + default: + return false; + } +} + +function isDeclarationName(name: ts.Identifier): boolean { + return isDeclaration(name.parent) && name.parent.name === name; +} \ No newline at end of file diff --git a/build-tests/api-documenter-test/etc/api-documenter-test.api.json b/build-tests/api-documenter-test/etc/api-documenter-test.api.json index f080ab2777f..c66889f1b1e 100644 --- a/build-tests/api-documenter-test/etc/api-documenter-test.api.json +++ b/build-tests/api-documenter-test/etc/api-documenter-test.api.json @@ -135,7 +135,8 @@ }, { "kind": "Reference", - "text": "DocBaseClass" + "text": "DocBaseClass", + "canonicalReference": "api-documenter-test!DocBaseClass:class" }, { "kind": "Content", @@ -147,7 +148,8 @@ }, { "kind": "Reference", - "text": "IDocInterface1" + "text": "IDocInterface1", + "canonicalReference": "api-documenter-test!IDocInterface1:interface" }, { "kind": "Content", @@ -155,7 +157,8 @@ }, { "kind": "Reference", - "text": "IDocInterface2" + "text": "IDocInterface2", + "canonicalReference": "api-documenter-test!IDocInterface2:interface" }, { "kind": "Content", @@ -379,7 +382,8 @@ }, { "kind": "Reference", - "text": "SystemEvent" + "text": "SystemEvent", + "canonicalReference": "api-documenter-test!SystemEvent:class" }, { "kind": "Content", @@ -413,7 +417,8 @@ }, { "kind": "Reference", - "text": "SystemEvent" + "text": "SystemEvent", + "canonicalReference": "api-documenter-test!SystemEvent:class" }, { "kind": "Content", @@ -443,7 +448,8 @@ }, { "kind": "Reference", - "text": "SystemEvent" + "text": "SystemEvent", + "canonicalReference": "api-documenter-test!SystemEvent:class" }, { "kind": "Content", @@ -754,7 +760,8 @@ }, { "kind": "Reference", - "text": "Promise" + "text": "Promise", + "canonicalReference": "!Promise:interface" }, { "kind": "Content", @@ -911,7 +918,8 @@ }, { "kind": "Reference", - "text": "SystemEvent" + "text": "SystemEvent", + "canonicalReference": "api-documenter-test!SystemEvent:class" }, { "kind": "Content", @@ -947,7 +955,8 @@ }, { "kind": "Reference", - "text": "IDocInterface1" + "text": "IDocInterface1", + "canonicalReference": "api-documenter-test!IDocInterface1:interface" }, { "kind": "Content", @@ -1053,15 +1062,8 @@ }, { "kind": "Reference", - "text": "EcmaSmbols" - }, - { - "kind": "Content", - "text": "." - }, - { - "kind": "Reference", - "text": "example" + "text": "EcmaSmbols.example", + "canonicalReference": "api-documenter-test!EcmaSmbols.example" }, { "kind": "Content", @@ -1079,8 +1081,8 @@ "releaseTag": "Public", "name": "[EcmaSmbols.example]", "propertyTypeTokenRange": { - "startIndex": 5, - "endIndex": 6 + "startIndex": 3, + "endIndex": 4 } }, { @@ -1144,7 +1146,8 @@ }, { "kind": "Reference", - "text": "IDocInterface1" + "text": "IDocInterface1", + "canonicalReference": "api-documenter-test!IDocInterface1:interface" }, { "kind": "Content", @@ -1318,7 +1321,8 @@ }, { "kind": "Reference", - "text": "Generic" + "text": "Generic", + "canonicalReference": "api-documenter-test!Generic:class" }, { "kind": "Content", @@ -1471,6 +1475,157 @@ "releaseTag": "Public", "name": "IDocInterface6", "members": [ + { + "kind": "PropertySignature", + "canonicalReference": "api-documenter-test!IDocInterface6#arrayProperty:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Reference", + "text": "arrayProperty" + }, + { + "kind": "Content", + "text": ": " + }, + { + "kind": "Reference", + "text": "IDocInterface1", + "canonicalReference": "api-documenter-test!IDocInterface1:interface" + }, + { + "kind": "Content", + "text": "[]" + }, + { + "kind": "Content", + "text": ";" + } + ], + "releaseTag": "Public", + "name": "arrayProperty", + "propertyTypeTokenRange": { + "startIndex": 2, + "endIndex": 4 + } + }, + { + "kind": "MethodSignature", + "canonicalReference": "api-documenter-test!IDocInterface6#genericReferenceMethod:member(1)", + "docComment": "", + "excerptTokens": [ + { + "kind": "Reference", + "text": "genericReferenceMethod" + }, + { + "kind": "Content", + "text": "<" + }, + { + "kind": "Reference", + "text": "T" + }, + { + "kind": "Content", + "text": ">(" + }, + { + "kind": "Reference", + "text": "x" + }, + { + "kind": "Content", + "text": ": " + }, + { + "kind": "Reference", + "text": "T", + "canonicalReference": "T" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Reference", + "text": "T", + "canonicalReference": "T" + }, + { + "kind": "Content", + "text": ";" + } + ], + "returnTypeTokenRange": { + "startIndex": 8, + "endIndex": 9 + }, + "releaseTag": "Public", + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "x", + "parameterTypeTokenRange": { + "startIndex": 6, + "endIndex": 7 + } + } + ], + "typeParameters": [ + { + "typeParameterName": "T", + "constraintTokenRange": { + "startIndex": 0, + "endIndex": 0 + }, + "defaultTypeTokenRange": { + "startIndex": 0, + "endIndex": 0 + } + } + ], + "name": "genericReferenceMethod" + }, + { + "kind": "PropertySignature", + "canonicalReference": "api-documenter-test!IDocInterface6#intersectionProperty:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Reference", + "text": "intersectionProperty" + }, + { + "kind": "Content", + "text": ": " + }, + { + "kind": "Reference", + "text": "IDocInterface1", + "canonicalReference": "api-documenter-test!IDocInterface1:interface" + }, + { + "kind": "Content", + "text": " & " + }, + { + "kind": "Reference", + "text": "IDocInterface2", + "canonicalReference": "api-documenter-test!IDocInterface2:interface" + }, + { + "kind": "Content", + "text": ";" + } + ], + "releaseTag": "Public", + "name": "intersectionProperty", + "propertyTypeTokenRange": { + "startIndex": 2, + "endIndex": 5 + } + }, { "kind": "PropertySignature", "canonicalReference": "api-documenter-test!IDocInterface6#regularProperty:member", @@ -1499,6 +1654,135 @@ "startIndex": 2, "endIndex": 3 } + }, + { + "kind": "PropertySignature", + "canonicalReference": "api-documenter-test!IDocInterface6#tupleProperty:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Reference", + "text": "tupleProperty" + }, + { + "kind": "Content", + "text": ": " + }, + { + "kind": "Content", + "text": "[" + }, + { + "kind": "Reference", + "text": "IDocInterface1", + "canonicalReference": "api-documenter-test!IDocInterface1:interface" + }, + { + "kind": "Content", + "text": ", " + }, + { + "kind": "Reference", + "text": "IDocInterface2", + "canonicalReference": "api-documenter-test!IDocInterface2:interface" + }, + { + "kind": "Content", + "text": "]" + }, + { + "kind": "Content", + "text": ";" + } + ], + "releaseTag": "Public", + "name": "tupleProperty", + "propertyTypeTokenRange": { + "startIndex": 2, + "endIndex": 7 + } + }, + { + "kind": "PropertySignature", + "canonicalReference": "api-documenter-test!IDocInterface6#typeReferenceProperty:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Reference", + "text": "typeReferenceProperty" + }, + { + "kind": "Content", + "text": ": " + }, + { + "kind": "Reference", + "text": "Generic", + "canonicalReference": "api-documenter-test!Generic:class" + }, + { + "kind": "Content", + "text": "<" + }, + { + "kind": "Reference", + "text": "IDocInterface1", + "canonicalReference": "api-documenter-test!IDocInterface1:interface" + }, + { + "kind": "Content", + "text": ">" + }, + { + "kind": "Content", + "text": ";" + } + ], + "releaseTag": "Public", + "name": "typeReferenceProperty", + "propertyTypeTokenRange": { + "startIndex": 2, + "endIndex": 6 + } + }, + { + "kind": "PropertySignature", + "canonicalReference": "api-documenter-test!IDocInterface6#unionProperty:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Reference", + "text": "unionProperty" + }, + { + "kind": "Content", + "text": ": " + }, + { + "kind": "Reference", + "text": "IDocInterface1", + "canonicalReference": "api-documenter-test!IDocInterface1:interface" + }, + { + "kind": "Content", + "text": " | " + }, + { + "kind": "Reference", + "text": "IDocInterface2", + "canonicalReference": "api-documenter-test!IDocInterface2:interface" + }, + { + "kind": "Content", + "text": ";" + } + ], + "releaseTag": "Public", + "name": "unionProperty", + "propertyTypeTokenRange": { + "startIndex": 2, + "endIndex": 5 + } } ], "extendsTokenRanges": [] diff --git a/build-tests/api-documenter-test/etc/api-documenter-test.api.md b/build-tests/api-documenter-test/etc/api-documenter-test.api.md index d6a0b732545..46d3270988a 100644 --- a/build-tests/api-documenter-test/etc/api-documenter-test.api.md +++ b/build-tests/api-documenter-test/etc/api-documenter-test.api.md @@ -94,6 +94,22 @@ export interface IDocInterface6 { regularProperty: number; } +// @public +export interface IDocInterface6 { + // (undocumented) + arrayProperty: IDocInterface1[]; + // (undocumented) + genericReferenceMethod(x: T): T; + // (undocumented) + intersectionProperty: IDocInterface1 & IDocInterface2; + // (undocumented) + tupleProperty: [IDocInterface1, IDocInterface2]; + // (undocumented) + typeReferenceProperty: Generic; + // (undocumented) + unionProperty: IDocInterface1 | IDocInterface2; +} + // @public export namespace OuterNamespace { export namespace InnerNamespace { diff --git a/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.arrayproperty.md b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.arrayproperty.md new file mode 100644 index 00000000000..aee7a495e71 --- /dev/null +++ b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.arrayproperty.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [api-documenter-test](./api-documenter-test.md) > [IDocInterface6](./api-documenter-test.idocinterface6.md) > [arrayProperty](./api-documenter-test.idocinterface6.arrayproperty.md) + +## IDocInterface6.arrayProperty property + +Signature: + +```typescript +arrayProperty: IDocInterface1[]; +``` diff --git a/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.genericreferencemethod.md b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.genericreferencemethod.md new file mode 100644 index 00000000000..a1bacf13445 --- /dev/null +++ b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.genericreferencemethod.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [api-documenter-test](./api-documenter-test.md) > [IDocInterface6](./api-documenter-test.idocinterface6.md) > [genericReferenceMethod](./api-documenter-test.idocinterface6.genericreferencemethod.md) + +## IDocInterface6.genericReferenceMethod() method + +Signature: + +```typescript +genericReferenceMethod(x: T): T; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| x | T | | + +Returns: + +`T` + diff --git a/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.intersectionproperty.md b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.intersectionproperty.md new file mode 100644 index 00000000000..ba405892095 --- /dev/null +++ b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.intersectionproperty.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [api-documenter-test](./api-documenter-test.md) > [IDocInterface6](./api-documenter-test.idocinterface6.md) > [intersectionProperty](./api-documenter-test.idocinterface6.intersectionproperty.md) + +## IDocInterface6.intersectionProperty property + +Signature: + +```typescript +intersectionProperty: IDocInterface1 & IDocInterface2; +``` diff --git a/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.md b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.md index 093407f82e5..19b351fe193 100644 --- a/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.md +++ b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.md @@ -16,5 +16,16 @@ export interface IDocInterface6 | Property | Type | Description | | --- | --- | --- | +| [arrayProperty](./api-documenter-test.idocinterface6.arrayproperty.md) | IDocInterface1[] | | +| [intersectionProperty](./api-documenter-test.idocinterface6.intersectionproperty.md) | IDocInterface1 & IDocInterface2 | | | [regularProperty](./api-documenter-test.idocinterface6.regularproperty.md) | number | Property of type number that does something | +| [tupleProperty](./api-documenter-test.idocinterface6.tupleproperty.md) | [IDocInterface1, IDocInterface2] | | +| [typeReferenceProperty](./api-documenter-test.idocinterface6.typereferenceproperty.md) | Generic<IDocInterface1> | | +| [unionProperty](./api-documenter-test.idocinterface6.unionproperty.md) | IDocInterface1 | IDocInterface2 | | + +## Methods + +| Method | Description | +| --- | --- | +| [genericReferenceMethod(x)](./api-documenter-test.idocinterface6.genericreferencemethod.md) | | diff --git a/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.tupleproperty.md b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.tupleproperty.md new file mode 100644 index 00000000000..c1732ee3106 --- /dev/null +++ b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.tupleproperty.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [api-documenter-test](./api-documenter-test.md) > [IDocInterface6](./api-documenter-test.idocinterface6.md) > [tupleProperty](./api-documenter-test.idocinterface6.tupleproperty.md) + +## IDocInterface6.tupleProperty property + +Signature: + +```typescript +tupleProperty: [IDocInterface1, IDocInterface2]; +``` diff --git a/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.typereferenceproperty.md b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.typereferenceproperty.md new file mode 100644 index 00000000000..f6df24d6005 --- /dev/null +++ b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.typereferenceproperty.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [api-documenter-test](./api-documenter-test.md) > [IDocInterface6](./api-documenter-test.idocinterface6.md) > [typeReferenceProperty](./api-documenter-test.idocinterface6.typereferenceproperty.md) + +## IDocInterface6.typeReferenceProperty property + +Signature: + +```typescript +typeReferenceProperty: Generic; +``` diff --git a/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.unionproperty.md b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.unionproperty.md new file mode 100644 index 00000000000..35139d8a9b8 --- /dev/null +++ b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.idocinterface6.unionproperty.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [api-documenter-test](./api-documenter-test.md) > [IDocInterface6](./api-documenter-test.idocinterface6.md) > [unionProperty](./api-documenter-test.idocinterface6.unionproperty.md) + +## IDocInterface6.unionProperty property + +Signature: + +```typescript +unionProperty: IDocInterface1 | IDocInterface2; +``` diff --git a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/docclass1.yml b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/docclass1.yml index 3c79ffd20bb..330d469d40a 100644 --- a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/docclass1.yml +++ b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/docclass1.yml @@ -172,3 +172,12 @@ items: type: - void description: '' +references: + - uid: 'api-documenter-test!DocBaseClass:class' + name: DocBaseClass + - uid: 'api-documenter-test!IDocInterface1:interface' + name: IDocInterface1 + - uid: 'api-documenter-test!IDocInterface2:interface' + name: IDocInterface2 + - uid: 'api-documenter-test!SystemEvent:class' + name: SystemEvent diff --git a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface1.yml b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface1.yml index 0c94b25019b..46167bbe571 100644 --- a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface1.yml +++ b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface1.yml @@ -21,3 +21,6 @@ items: return: type: - 'api-documenter-test!SystemEvent:class' +references: + - uid: 'api-documenter-test!SystemEvent:class' + name: SystemEvent diff --git a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface2.yml b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface2.yml index 71a94e3a4f3..66afe8a14d3 100644 --- a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface2.yml +++ b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface2.yml @@ -25,3 +25,6 @@ items: type: - void description: '' +references: + - uid: 'api-documenter-test!IDocInterface1:interface' + name: IDocInterface1 diff --git a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface4.yml b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface4.yml index 8653fc1fb18..af1f8ed516d 100644 --- a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface4.yml +++ b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface4.yml @@ -27,10 +27,7 @@ items: }) => boolean; return: type: - - |- - ({ children }: { - children: string; - }) => boolean + - 'api-documenter-test!IDocInterface4#Context~0:complex' - uid: 'api-documenter-test!IDocInterface4#generic:member' summary: make sure html entities are escaped in tables. name: generic @@ -42,7 +39,7 @@ items: content: 'generic: Generic;' return: type: - - Generic + - 'api-documenter-test!IDocInterface4#generic~0:complex' - uid: 'api-documenter-test!IDocInterface4#numberOrFunction:member' summary: a union type with a function name: numberOrFunction @@ -67,3 +64,43 @@ items: return: type: - string | number +references: + - uid: 'api-documenter-test!IDocInterface4#Context~0:complex' + name: |- + ({ children }: { + children: string; + }) => boolean + fullName: |- + ({ children }: { + children: string; + }) => boolean + spec.typeScript: + - name: '({ ' + fullName: '({ ' + - uid: children + name: children + fullName: children + - name: |2- + }: { + + fullName: |2- + }: { + + - uid: children + name: children + fullName: children + - name: |- + : string; + }) => boolean + fullName: |- + : string; + }) => boolean + - uid: 'api-documenter-test!IDocInterface4#generic~0:complex' + name: Generic + fullName: Generic + spec.typeScript: + - uid: 'api-documenter-test!Generic:class' + name: Generic + fullName: Generic + - name: + fullName: diff --git a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface6.yml b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface6.yml index 46d02be19e5..8b84d736d5a 100644 --- a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface6.yml +++ b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface6.yml @@ -9,7 +9,54 @@ items: type: interface package: api-documenter-test! children: + - 'api-documenter-test!IDocInterface6#arrayProperty:member' + - 'api-documenter-test!IDocInterface6#genericReferenceMethod:member(1)' + - 'api-documenter-test!IDocInterface6#intersectionProperty:member' - 'api-documenter-test!IDocInterface6#regularProperty:member' + - 'api-documenter-test!IDocInterface6#tupleProperty:member' + - 'api-documenter-test!IDocInterface6#typeReferenceProperty:member' + - 'api-documenter-test!IDocInterface6#unionProperty:member' + - uid: 'api-documenter-test!IDocInterface6#arrayProperty:member' + name: arrayProperty + fullName: arrayProperty + langs: + - typeScript + type: property + syntax: + content: 'arrayProperty: IDocInterface1[];' + return: + type: + - 'api-documenter-test!IDocInterface6#arrayProperty~0:complex' + - uid: 'api-documenter-test!IDocInterface6#genericReferenceMethod:member(1)' + name: genericReferenceMethod(x) + fullName: genericReferenceMethod(x) + langs: + - typeScript + type: method + syntax: + content: 'genericReferenceMethod(x: T): T;' + return: + type: + - T + description: '' + parameters: + - id: x + description: '' + type: + - T + typeParameters: + - id: T + - uid: 'api-documenter-test!IDocInterface6#intersectionProperty:member' + name: intersectionProperty + fullName: intersectionProperty + langs: + - typeScript + type: property + syntax: + content: 'intersectionProperty: IDocInterface1 & IDocInterface2;' + return: + type: + - 'api-documenter-test!IDocInterface6#intersectionProperty~0:complex' - uid: 'api-documenter-test!IDocInterface6#regularProperty:member' summary: Property of type number that does something name: regularProperty @@ -22,3 +69,101 @@ items: return: type: - number + - uid: 'api-documenter-test!IDocInterface6#tupleProperty:member' + name: tupleProperty + fullName: tupleProperty + langs: + - typeScript + type: property + syntax: + content: 'tupleProperty: [IDocInterface1, IDocInterface2];' + return: + type: + - 'api-documenter-test!IDocInterface6#tupleProperty~0:complex' + - uid: 'api-documenter-test!IDocInterface6#typeReferenceProperty:member' + name: typeReferenceProperty + fullName: typeReferenceProperty + langs: + - typeScript + type: property + syntax: + content: 'typeReferenceProperty: Generic;' + return: + type: + - 'api-documenter-test!IDocInterface6#typeReferenceProperty~0:complex' + - uid: 'api-documenter-test!IDocInterface6#unionProperty:member' + name: unionProperty + fullName: unionProperty + langs: + - typeScript + type: property + syntax: + content: 'unionProperty: IDocInterface1 | IDocInterface2;' + return: + type: + - 'api-documenter-test!IDocInterface6#unionProperty~0:complex' +references: + - uid: 'api-documenter-test!IDocInterface6#arrayProperty~0:complex' + name: 'IDocInterface1[]' + fullName: 'IDocInterface1[]' + spec.typeScript: + - uid: 'api-documenter-test!IDocInterface1:interface' + name: IDocInterface1 + fullName: IDocInterface1 + - name: '[]' + fullName: '[]' + - uid: T + - uid: 'api-documenter-test!IDocInterface6#intersectionProperty~0:complex' + name: IDocInterface1 & IDocInterface2 + fullName: IDocInterface1 & IDocInterface2 + spec.typeScript: + - uid: 'api-documenter-test!IDocInterface1:interface' + name: IDocInterface1 + fullName: IDocInterface1 + - name: ' & ' + fullName: ' & ' + - uid: 'api-documenter-test!IDocInterface2:interface' + name: IDocInterface2 + fullName: IDocInterface2 + - uid: 'api-documenter-test!IDocInterface6#tupleProperty~0:complex' + name: '[IDocInterface1, IDocInterface2]' + fullName: '[IDocInterface1, IDocInterface2]' + spec.typeScript: + - name: '[' + fullName: '[' + - uid: 'api-documenter-test!IDocInterface1:interface' + name: IDocInterface1 + fullName: IDocInterface1 + - name: ', ' + fullName: ', ' + - uid: 'api-documenter-test!IDocInterface2:interface' + name: IDocInterface2 + fullName: IDocInterface2 + - name: ']' + fullName: ']' + - uid: 'api-documenter-test!IDocInterface6#typeReferenceProperty~0:complex' + name: Generic + fullName: Generic + spec.typeScript: + - uid: 'api-documenter-test!Generic:class' + name: Generic + fullName: Generic + - name: < + fullName: < + - uid: 'api-documenter-test!IDocInterface1:interface' + name: IDocInterface1 + fullName: IDocInterface1 + - name: '>' + fullName: '>' + - uid: 'api-documenter-test!IDocInterface6#unionProperty~0:complex' + name: IDocInterface1 | IDocInterface2 + fullName: IDocInterface1 | IDocInterface2 + spec.typeScript: + - uid: 'api-documenter-test!IDocInterface1:interface' + name: IDocInterface1 + fullName: IDocInterface1 + - name: ' | ' + fullName: ' | ' + - uid: 'api-documenter-test!IDocInterface2:interface' + name: IDocInterface2 + fullName: IDocInterface2 diff --git a/build-tests/api-documenter-test/src/DocClass1.ts b/build-tests/api-documenter-test/src/DocClass1.ts index d7c5ee23501..a660de56552 100644 --- a/build-tests/api-documenter-test/src/DocClass1.ts +++ b/build-tests/api-documenter-test/src/DocClass1.ts @@ -264,3 +264,16 @@ export interface IDocInterface6 { */ regularProperty: number; } + +/** + * Interface for testing complex properties + * @public + */ +export interface IDocInterface6 { + arrayProperty: IDocInterface1[]; + tupleProperty: [IDocInterface1, IDocInterface2]; + unionProperty: IDocInterface1 | IDocInterface2; + intersectionProperty: IDocInterface1 & IDocInterface2; + typeReferenceProperty: Generic; + genericReferenceMethod(x: T): T; +} \ No newline at end of file diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/ambientNameConflict/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/ambientNameConflict/api-extractor-scenarios.api.json index 80b89247e6c..a74b19ed394 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/ambientNameConflict/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/ambientNameConflict/api-extractor-scenarios.api.json @@ -42,7 +42,8 @@ }, { "kind": "Reference", - "text": "Promise" + "text": "Promise", + "canonicalReference": "!Promise:interface" }, { "kind": "Content", @@ -62,7 +63,8 @@ }, { "kind": "Reference", - "text": "MyPromise" + "text": "MyPromise", + "canonicalReference": "api-extractor-scenarios!Promise:class" }, { "kind": "Content", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/apiItemKinds/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/apiItemKinds/api-extractor-scenarios.api.json index f8884decec2..017fc128235 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/apiItemKinds/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/apiItemKinds/api-extractor-scenarios.api.json @@ -195,7 +195,8 @@ }, { "kind": "Reference", - "text": "ClassWithTypeLiterals" + "text": "ClassWithTypeLiterals", + "canonicalReference": "api-extractor-scenarios!ClassWithTypeLiterals:class" }, { "kind": "Content", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport/api-extractor-scenarios.api.json index 9f51db8953c..d78684206ae 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport/api-extractor-scenarios.api.json @@ -51,7 +51,8 @@ }, { "kind": "Reference", - "text": "IFolder" + "text": "IFolder", + "canonicalReference": "api-extractor-scenarios!IFolder:class" }, { "kind": "Content", @@ -105,7 +106,8 @@ }, { "kind": "Reference", - "text": "IFolder" + "text": "IFolder", + "canonicalReference": "api-extractor-scenarios!IFolder:class" }, { "kind": "Content", @@ -139,7 +141,8 @@ }, { "kind": "Reference", - "text": "IFile" + "text": "IFile", + "canonicalReference": "api-extractor-scenarios!IFile:class" }, { "kind": "Content", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport2/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport2/api-extractor-scenarios.api.json index 0a61210d03b..08c03f40115 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport2/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport2/api-extractor-scenarios.api.json @@ -97,7 +97,8 @@ }, { "kind": "Reference", - "text": "IFolder" + "text": "IFolder", + "canonicalReference": "api-extractor-scenarios!IFolder:class" }, { "kind": "Content", @@ -151,7 +152,8 @@ }, { "kind": "Reference", - "text": "IFolder" + "text": "IFolder", + "canonicalReference": "api-extractor-scenarios!IFolder:class" }, { "kind": "Content", @@ -185,7 +187,8 @@ }, { "kind": "Reference", - "text": "IFile" + "text": "IFile", + "canonicalReference": "api-extractor-scenarios!IFile:class" }, { "kind": "Content", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/exportEquals/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/exportEquals/api-extractor-scenarios.api.json index 7ce7c81c2d7..824e025a995 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/exportEquals/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/exportEquals/api-extractor-scenarios.api.json @@ -51,7 +51,8 @@ }, { "kind": "Reference", - "text": "Context" + "text": "Context", + "canonicalReference": "!microsoftTeams.Context:interface" }, { "kind": "Content", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/importEquals/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/importEquals/api-extractor-scenarios.api.json index c598779508c..bf2dc44a839 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/importEquals/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/importEquals/api-extractor-scenarios.api.json @@ -38,15 +38,8 @@ }, { "kind": "Reference", - "text": "colors" - }, - { - "kind": "Content", - "text": "." - }, - { - "kind": "Reference", - "text": "zebra" + "text": "colors.zebra", + "canonicalReference": "colors!zebra:var" }, { "kind": "Content", @@ -55,7 +48,7 @@ ], "returnTypeTokenRange": { "startIndex": 3, - "endIndex": 7 + "endIndex": 5 }, "releaseTag": "Public", "overloadIndex": 1, diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/inconsistentReleaseTags/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/inconsistentReleaseTags/api-extractor-scenarios.api.json index 3c21db50c5e..b3a58aeb6ac 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/inconsistentReleaseTags/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/inconsistentReleaseTags/api-extractor-scenarios.api.json @@ -87,7 +87,8 @@ }, { "kind": "Reference", - "text": "IBeta" + "text": "IBeta", + "canonicalReference": "api-extractor-scenarios!IBeta:interface" }, { "kind": "Content", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf/api-extractor-scenarios.api.json index 453042c127d..1fb627d47d7 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf/api-extractor-scenarios.api.json @@ -38,7 +38,8 @@ }, { "kind": "Reference", - "text": "Lib1Class" + "text": "Lib1Class", + "canonicalReference": "api-extractor-lib1-test!Lib1Class:class" }, { "kind": "Content", @@ -81,7 +82,8 @@ }, { "kind": "Reference", - "text": "ForgottenExport" + "text": "ForgottenExport", + "canonicalReference": "!ForgottenExport:class" }, { "kind": "Content", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/typeParameters/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/typeParameters/api-extractor-scenarios.api.json index 189423755b5..693d39328aa 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/typeParameters/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/typeParameters/api-extractor-scenarios.api.json @@ -367,7 +367,8 @@ }, { "kind": "Reference", - "text": "T" + "text": "T", + "canonicalReference": "T" }, { "kind": "Content", @@ -505,7 +506,8 @@ }, { "kind": "Reference", - "text": "T" + "text": "T", + "canonicalReference": "T" }, { "kind": "Content", diff --git a/common/changes/@microsoft/api-documenter/deeplyLinkedTypes_2019-06-09-00-46.json b/common/changes/@microsoft/api-documenter/deeplyLinkedTypes_2019-06-09-00-46.json new file mode 100644 index 00000000000..70055bf3cc9 --- /dev/null +++ b/common/changes/@microsoft/api-documenter/deeplyLinkedTypes_2019-06-09-00-46.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@microsoft/api-documenter", + "comment": "Add support for emitting deeply linked types in YamlDocumenter", + "type": "patch" + } + ], + "packageName": "@microsoft/api-documenter", + "email": "ron.buckton@microsoft.com" +} \ No newline at end of file diff --git a/common/reviews/api/api-extractor-model.api.md b/common/reviews/api/api-extractor-model.api.md index 275ca794fc7..8e30a99730a 100644 --- a/common/reviews/api/api-extractor-model.api.md +++ b/common/reviews/api/api-extractor-model.api.md @@ -613,12 +613,18 @@ export class Excerpt { // @public (undocumented) export class ExcerptToken { - constructor(kind: ExcerptTokenKind, text: string); + constructor(kind: ExcerptTokenKind, text: string, canonicalReference?: DeclarationReference); + // (undocumented) + readonly canonicalReference: DeclarationReference | undefined; + // (undocumented) + static fromJSON(object: IExcerptToken): ExcerptToken; // (undocumented) readonly kind: ExcerptTokenKind; // (undocumented) readonly text: string; - } + // (undocumented) + toJSON(): IExcerptToken; +} // @public (undocumented) export const enum ExcerptTokenKind { @@ -815,6 +821,8 @@ export interface IApiVariableOptions extends IApiNameMixinOptions, IApiReleaseTa // @public (undocumented) export interface IExcerptToken { + // (undocumented) + canonicalReference?: string; // (undocumented) readonly kind: ExcerptTokenKind; // (undocumented) From d1f1bfeb7eb823638c637d1b662ad1936fc8412b Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 6 Sep 2019 13:09:32 -0700 Subject: [PATCH 2/8] Cleanup _renderType, remove _linkToUidIfPossible and related members --- .../src/documenters/YamlDocumenter.ts | 228 +++++++----------- .../api-documenter-test/idocinterface4.yml | 35 +-- .../deeplyLinkedtypes_2019-09-06-20-19.json | 11 + .../deeplyLinkedtypes_2019-09-06-20-19.json | 11 + 4 files changed, 107 insertions(+), 178 deletions(-) create mode 100644 common/changes/@microsoft/api-extractor-model/deeplyLinkedtypes_2019-09-06-20-19.json create mode 100644 common/changes/@microsoft/api-extractor/deeplyLinkedtypes_2019-09-06-20-19.json diff --git a/apps/api-documenter/src/documenters/YamlDocumenter.ts b/apps/api-documenter/src/documenters/YamlDocumenter.ts index b91183526e8..c52f732314a 100644 --- a/apps/api-documenter/src/documenters/YamlDocumenter.ts +++ b/apps/api-documenter/src/documenters/YamlDocumenter.ts @@ -60,6 +60,11 @@ import { CustomMarkdownEmitter} from '../markdown/CustomMarkdownEmitter'; const yamlApiSchema: JsonSchema = JsonSchema.fromFile(path.join(__dirname, '..', 'yaml', 'typescript.schema.json')); +interface IYamlReferences { + references: IYamlReference[]; + typeNameToUid: Map; +} + /** * Writes documentation in the Universal Reference YAML file format, as defined by typescript.schema.json. */ @@ -67,14 +72,9 @@ export class YamlDocumenter { private readonly _apiModel: ApiModel; private readonly _markdownEmitter: CustomMarkdownEmitter; - // This is used by the _linkToUidIfPossible() workaround. - // It stores a mapping from type name (e.g. "MyClass") to the corresponding ApiItem. - // If the mapping would be ambiguous (e.g. "MyClass" is defined by multiple packages) - // then it is excluded from the mapping. Also excluded are ApiItem objects (such as package - // and function) which are not typically used as a data type. - private _apiItemsByTypeName: Map; + private _apiItemsByCanonicalReference: Map; private _knownTypeParameters: Set | undefined; - private _yamlReferences: IYamlReference[] | undefined; + private _yamlReferences: IYamlReferences | undefined; private _uidTypeReferenceCounters: Map; private _outputFolder: string; @@ -82,10 +82,10 @@ export class YamlDocumenter { public constructor(apiModel: ApiModel) { this._apiModel = apiModel; this._markdownEmitter = new CustomMarkdownEmitter(this._apiModel); - this._apiItemsByTypeName = new Map(); + this._apiItemsByCanonicalReference = new Map(); this._uidTypeReferenceCounters = new Map(); - this._initApiItemsByTypeName(); + this._initApiItems(); } /** @virtual */ @@ -171,11 +171,11 @@ export class YamlDocumenter { } if (this._yamlReferences) { - if (this._yamlReferences.length > 0) { + if (this._yamlReferences.references.length > 0) { if (newYamlFile.references) { - newYamlFile.references = [...newYamlFile.references, ...this._yamlReferences]; + newYamlFile.references = [...newYamlFile.references, ...this._yamlReferences.references]; } else { - newYamlFile.references = this._yamlReferences; + newYamlFile.references = this._yamlReferences.references; } } this._yamlReferences = undefined; @@ -609,97 +609,39 @@ export class YamlDocumenter { } /** - * Initialize the _apiItemsByTypeName data structure. + * Initialize the _apiItemsByCanonicalReference data structure. */ - private _initApiItemsByTypeName(): void { - // Collect the _apiItemsByTypeName table - const ambiguousNames: Set = new Set(); - - this._initApiItemsByTypeNameRecursive(this._apiModel, ambiguousNames); + private _initApiItems(): void { + this._initApiItemsRecursive(this._apiModel); - // Remove the ambiguous matches - for (const ambiguousName of ambiguousNames) { - this._apiItemsByTypeName.delete(ambiguousName); - } } /** - * Helper for _initApiItemsByTypeName() + * Helper for _initApiItems() */ - private _initApiItemsByTypeNameRecursive(apiItem: ApiItem, ambiguousNames: Set): void { - switch (apiItem.kind) { - case ApiItemKind.Class: - case ApiItemKind.Enum: - case ApiItemKind.Interface: - // Attempt to register both the fully qualified name and the short name - const namesForType: string[] = [apiItem.displayName]; - - // Note that nameWithDot cannot conflict with apiItem.name (because apiItem.name - // cannot contain a dot) - const nameWithDot: string | undefined = this._getTypeNameWithDot(apiItem); - if (nameWithDot) { - namesForType.push(nameWithDot); - } - - // Register all names - for (const typeName of namesForType) { - if (ambiguousNames.has(typeName)) { - break; - } - - if (this._apiItemsByTypeName.has(typeName)) { - // We saw this name before, so it's an ambiguous match - ambiguousNames.add(typeName); - break; - } - - this._apiItemsByTypeName.set(typeName, apiItem); - } - - break; + private _initApiItemsRecursive(apiItem: ApiItem): void { + if (apiItem.canonicalReference && !apiItem.canonicalReference.isEmpty) { + this._apiItemsByCanonicalReference.set(apiItem.canonicalReference.toString(), apiItem); } // Recurse container members if (ApiItemContainerMixin.isBaseClassOf(apiItem)) { for (const apiMember of apiItem.members) { - this._initApiItemsByTypeNameRecursive(apiMember, ambiguousNames); + this._initApiItemsRecursive(apiMember); } } } - private _ensureYamlReferences(): IYamlReference[] { + private _ensureYamlReferences(): IYamlReferences { if (!this._yamlReferences) { - this._yamlReferences = []; + this._yamlReferences = { + references: [], + typeNameToUid: new Map() + }; } return this._yamlReferences; } - /** - * This is a temporary workaround to enable limited autolinking of API item types - * until the YAML file format is enhanced to support general hyperlinks. - * @remarks - * In the current version, fields such as IApiProperty.type allow either: - * (1) a UID identifier such as "node-core-library.JsonFile" which will be rendered - * as a hyperlink to that type name, or (2) a block of freeform text that must not - * contain any Markdown links. The _substituteUidForSimpleType() function assumes - * it is given #2 but substitutes #1 if the name can be matched to a ApiItem. - */ - private _linkToUidIfPossible(typeName: string): string | undefined { - typeName = typeName.trim(); - // Do not look up the UID for a type parameter, as we could inadvertently - // look up a different type with the same name. - if (this._knownTypeParameters && this._knownTypeParameters.has(typeName)) { - return typeName; - } - - // Note that typeName might be a _getTypeNameWithDot() name or it might be a simple class name - const apiItem: ApiItem | undefined = this._apiItemsByTypeName.get(typeName); - if (apiItem) { - // Substitute the UID - return this._getUid(apiItem); - } - } - private _renderType(contextUid: DeclarationReference, typeExcerpt: Excerpt): string { const excerptTokens: ExcerptToken[] = typeExcerpt.tokens.slice( typeExcerpt.tokenRange.startIndex, @@ -719,76 +661,87 @@ export class YamlDocumenter { } const typeName: string = typeExcerpt.text.trim(); + + // Record a reference to a type parameter as its name, so as not to resolve to a conflicting name + if (this._knownTypeParameters && this._knownTypeParameters.has(typeName)) { + return this._recordYamlReference(this._ensureYamlReferences(), typeName, typeName); + } + + // If there are no references to be used for a complex type, return the type name. + if (!excerptTokens.some(tok => tok.kind === ExcerptTokenKind.Reference && !!tok.canonicalReference)) { + return typeName; + } + + const yamlReferences: IYamlReferences = this._ensureYamlReferences(); + const existingUid: string | undefined = yamlReferences.typeNameToUid.get(typeName); + + // If this type has already been referenced for the current file, return its uid. + if (existingUid) { + return existingUid; + } + + // If the excerpt consists of a single reference token, record the reference. if (excerptTokens.length === 1 && excerptTokens[0].kind === ExcerptTokenKind.Reference && excerptTokens[0].canonicalReference) { return this._recordYamlReference( + yamlReferences, excerptTokens[0].canonicalReference.toString(), typeName ); } - const typeNameAsUid: string | undefined = this._linkToUidIfPossible(typeName); - if (typeNameAsUid !== undefined) { - if (typeNameAsUid !== typeName) { - return this._recordYamlReference(typeNameAsUid, typeName); - } - return typeNameAsUid; - } - - if (isEntityName(typeName)) { - return typeName; - } - - // If there are no references to be used for a complex type, return the type name. - if (!excerptTokens.some(tok => tok.kind === ExcerptTokenKind.Reference)) { - return typeName; - } - + // Otherwise, the type is complex and consists of one or more reference tokens. Record a reference + // and return its uid. const baseUid: string = contextUid .withMeaning(undefined) .withOverloadIndex(undefined) .toString(); + + // Keep track of the count for the base uid (without meaning or overload index) to ensure + // that each complex type reference is unique. const counter: number = this._uidTypeReferenceCounters.get(baseUid) || 0; + this._uidTypeReferenceCounters.set(baseUid, counter + 1); + const uid: string = contextUid .addNavigationStep(Navigation.Locals, `${counter}`) .withMeaning(Meaning.ComplexType) + .withOverloadIndex(undefined) .toString(); - this._uidTypeReferenceCounters.set(baseUid, counter + 1); - this._recordYamlReference(uid, typeName, excerptTokens); - return uid; + + return this._recordYamlReference(yamlReferences, uid, typeName, excerptTokens); } - private _recordYamlReference(uid: string, typeName: string, excerptTokens?: ExcerptToken[]): string { - const yamlReferences: IYamlReference[] = this._ensureYamlReferences(); + private _recordYamlReference(yamlReferences: IYamlReferences, uid: string, typeName: string, + excerptTokens?: ExcerptToken[]): string { - if (yamlReferences.some(ref => ref.uid === uid)) { + if (yamlReferences.references.some(ref => ref.uid === uid)) { return uid; } // Fill in the reference spec from the excerpt. - const spec: IYamlReferenceSpec[] = []; + const specs: IYamlReferenceSpec[] = []; if (excerptTokens) { for (const token of excerptTokens) { if (token.kind === ExcerptTokenKind.Reference) { - let specUid: string | undefined = token.canonicalReference && token.canonicalReference.toString(); - const apiItem: ApiItem | undefined = this._apiItemsByTypeName.get(token.text); - if (specUid === undefined) { - if (apiItem) { - specUid = this._getUid(apiItem); - } else { - specUid = token.text; - } + const spec: IYamlReferenceSpec = { }; + const specUid: string | undefined = token.canonicalReference && token.canonicalReference.toString(); + const apiItem: ApiItem | undefined = specUid ? this._apiItemsByCanonicalReference.get(specUid) : undefined; + if (specUid) { + spec.uid = specUid; } - spec.push( - { - uid: specUid, - name: token.text, - fullName: apiItem ? apiItem.getScopedNameWithinPackage() : token.text - } - ); + spec.name = token.text; + spec.fullName = + apiItem ? apiItem.getScopedNameWithinPackage() : + token.canonicalReference ? token.canonicalReference + .withSource(undefined) + .withMeaning(undefined) + .withOverloadIndex(undefined) + .toString() : + token.text; + specs.push(spec); } else { - spec.push( + specs.push( { name: token.text, fullName: token.text @@ -799,31 +752,18 @@ export class YamlDocumenter { } const yamlReference: IYamlReference = { uid }; - if (spec.length > 0) { - yamlReference.name = spec.map(s => s.name).join('').trim(); - yamlReference.fullName = spec.map(s => s.fullName || s.name).join('').trim(); - yamlReference['spec.typeScript'] = spec; + if (specs.length > 0) { + yamlReference.name = specs.map(s => s.name).join('').trim(); + yamlReference.fullName = specs.map(s => s.fullName || s.name).join('').trim(); + yamlReference['spec.typeScript'] = specs; } else if (typeName !== uid) { yamlReference.name = typeName; } - yamlReferences.push(yamlReference); + yamlReferences.references.push(yamlReference); return uid; } - /** - * If the apiItem represents a scoped name such as "my-library#MyNamespace.MyClass", - * this returns a string such as "MyNamespace.MyClass". If the result would not - * have at least one dot in it, then undefined is returned. - */ - private _getTypeNameWithDot(apiItem: ApiItem): string | undefined { - const result: string = apiItem.getScopedNameWithinPackage(); - if (result.indexOf('.') >= 0) { - return result; - } - return undefined; - } - private _getYamlItemName(apiItem: ApiItem): string { if (apiItem.parent && apiItem.parent.kind === ApiItemKind.Namespace) { // If the immediate parent is a namespace, then add the namespaces to the name. For example: @@ -896,10 +836,4 @@ export class YamlDocumenter { console.log('Deleting old output from ' + this._outputFolder); FileSystem.ensureEmptyFolder(this._outputFolder); } -} - -const entityNameRegExp: RegExp = /^(?!\d)[\w$_]+(\.(?!\d)[\w$_]+)*$/; - -function isEntityName(text: string): boolean { - return entityNameRegExp.test(text); } \ No newline at end of file diff --git a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface4.yml b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface4.yml index af1f8ed516d..0f78d82db0a 100644 --- a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface4.yml +++ b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface4.yml @@ -27,7 +27,10 @@ items: }) => boolean; return: type: - - 'api-documenter-test!IDocInterface4#Context~0:complex' + - |- + ({ children }: { + children: string; + }) => boolean - uid: 'api-documenter-test!IDocInterface4#generic:member' summary: make sure html entities are escaped in tables. name: generic @@ -65,36 +68,6 @@ items: type: - string | number references: - - uid: 'api-documenter-test!IDocInterface4#Context~0:complex' - name: |- - ({ children }: { - children: string; - }) => boolean - fullName: |- - ({ children }: { - children: string; - }) => boolean - spec.typeScript: - - name: '({ ' - fullName: '({ ' - - uid: children - name: children - fullName: children - - name: |2- - }: { - - fullName: |2- - }: { - - - uid: children - name: children - fullName: children - - name: |- - : string; - }) => boolean - fullName: |- - : string; - }) => boolean - uid: 'api-documenter-test!IDocInterface4#generic~0:complex' name: Generic fullName: Generic diff --git a/common/changes/@microsoft/api-extractor-model/deeplyLinkedtypes_2019-09-06-20-19.json b/common/changes/@microsoft/api-extractor-model/deeplyLinkedtypes_2019-09-06-20-19.json new file mode 100644 index 00000000000..e0e0d345b81 --- /dev/null +++ b/common/changes/@microsoft/api-extractor-model/deeplyLinkedtypes_2019-09-06-20-19.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@microsoft/api-extractor-model", + "comment": "Add 'canonicalReference' to ExcerptToken", + "type": "minor" + } + ], + "packageName": "@microsoft/api-extractor-model", + "email": "ron.buckton@microsoft.com" +} \ No newline at end of file diff --git a/common/changes/@microsoft/api-extractor/deeplyLinkedtypes_2019-09-06-20-19.json b/common/changes/@microsoft/api-extractor/deeplyLinkedtypes_2019-09-06-20-19.json new file mode 100644 index 00000000000..06a0c326d15 --- /dev/null +++ b/common/changes/@microsoft/api-extractor/deeplyLinkedtypes_2019-09-06-20-19.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@microsoft/api-extractor", + "comment": "Add support for generating declaration references", + "type": "minor" + } + ], + "packageName": "@microsoft/api-extractor", + "email": "ron.buckton@microsoft.com" +} \ No newline at end of file From 33f8d0da34ad745f67b1cdfe63efd8090845c414 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sat, 7 Sep 2019 15:03:18 -0700 Subject: [PATCH 3/8] Remove ref from type params, improve uid generation for locals --- .../src/items/ApiDeclaredItem.ts | 15 ++- .../api-extractor-model/src/mixins/Excerpt.ts | 14 --- .../DeclarationReferenceGenerator.ts | 92 ++++++++++++++++--- .../etc/api-documenter-test.api.json | 6 +- .../typeOf/api-extractor-scenarios.api.json | 2 +- .../api-extractor-scenarios.api.json | 6 +- 6 files changed, 96 insertions(+), 39 deletions(-) diff --git a/apps/api-extractor-model/src/items/ApiDeclaredItem.ts b/apps/api-extractor-model/src/items/ApiDeclaredItem.ts index 6abefe7f1db..6809d799b3f 100644 --- a/apps/api-extractor-model/src/items/ApiDeclaredItem.ts +++ b/apps/api-extractor-model/src/items/ApiDeclaredItem.ts @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information.s +import { DeclarationReference } from '@microsoft/tsdoc/lib/beta/DeclarationReference'; import { ApiDocumentedItem, IApiDocumentedItemJson, IApiDocumentedItemOptions } from './ApiDocumentedItem'; import { Excerpt, ExcerptToken, IExcerptTokenRange, IExcerptToken } from '../mixins/Excerpt'; import { DeserializerContext } from '../model/DeserializerContext'; @@ -47,7 +48,11 @@ export class ApiDeclaredItem extends ApiDocumentedItem { public constructor(options: IApiDeclaredItemOptions) { super(options); - this._excerptTokens = options.excerptTokens.map(x => ExcerptToken.fromJSON(x)); + this._excerptTokens = options.excerptTokens.map(x => { + const canonicalReference: DeclarationReference | undefined = x.canonicalReference === undefined ? undefined : + DeclarationReference.parse(x.canonicalReference); + return new ExcerptToken(x.kind, x.text, canonicalReference); + }); this._excerpt = new Excerpt(this.excerptTokens, { startIndex: 0, endIndex: this.excerptTokens.length }); } @@ -99,7 +104,13 @@ export class ApiDeclaredItem extends ApiDocumentedItem { /** @override */ public serializeInto(jsonObject: Partial): void { super.serializeInto(jsonObject); - jsonObject.excerptTokens = this.excerptTokens.map(x => x.toJSON()); + jsonObject.excerptTokens = this.excerptTokens.map(x => { + const excerptToken: IExcerptToken = { kind: x.kind, text: x.text }; + if (x.canonicalReference !== undefined) { + excerptToken.canonicalReference = x.canonicalReference.toString(); + } + return excerptToken; + }); } /** diff --git a/apps/api-extractor-model/src/mixins/Excerpt.ts b/apps/api-extractor-model/src/mixins/Excerpt.ts index a5f5bce4a2b..d8b16a7282e 100644 --- a/apps/api-extractor-model/src/mixins/Excerpt.ts +++ b/apps/api-extractor-model/src/mixins/Excerpt.ts @@ -52,20 +52,6 @@ export class ExcerptToken { public get canonicalReference(): DeclarationReference | undefined { return this._canonicalReference; } - - public static fromJSON(object: IExcerptToken): ExcerptToken { - const canonicalReference: DeclarationReference | undefined = object.canonicalReference === undefined ? undefined : - DeclarationReference.parse(object.canonicalReference); - return new ExcerptToken(object.kind, object.text, canonicalReference); - } - - public toJSON(): IExcerptToken { - const excerptToken: IExcerptToken = { kind: this.kind, text: this.text }; - if (this._canonicalReference !== undefined) { - excerptToken.canonicalReference = this._canonicalReference.toString(); - } - return excerptToken; - } } /** diff --git a/apps/api-extractor/src/generators/DeclarationReferenceGenerator.ts b/apps/api-extractor/src/generators/DeclarationReferenceGenerator.ts index 707ef3550a2..0dd24bd41ff 100644 --- a/apps/api-extractor/src/generators/DeclarationReferenceGenerator.ts +++ b/apps/api-extractor/src/generators/DeclarationReferenceGenerator.ts @@ -72,14 +72,27 @@ export class DeclarationReferenceGenerator { return new DeclarationReference(this._sourceFileToModuleSource(sourceFile)); } + // Do not generate a declaration reference for a type parameter. if (symbol.flags & ts.SymbolFlags.TypeParameter) { - return DeclarationReference.parse(DeclarationReference.escapeComponentString(symbol.name)); + return undefined; } const parent: ts.Symbol | undefined = TypeScriptInternals.getSymbolParent(symbol); - const parentRef: DeclarationReference | undefined = parent - ? this._symbolToDeclarationReference(parent, ts.SymbolFlags.Namespace, /*includeModuleSymbols*/ true) - : new DeclarationReference(GlobalSource.instance); + let parentRef: DeclarationReference | undefined; + if (parent) { + parentRef = this._symbolToDeclarationReference(parent, ts.SymbolFlags.Namespace, /*includeModuleSymbols*/ true); + } else { + // this may be a local symbol in a module... + const sourceFile: ts.SourceFile | undefined = + symbol.declarations + && symbol.declarations[0] + && symbol.declarations[0].getSourceFile(); + if (ts.isExternalModule(sourceFile)) { + parentRef = new DeclarationReference(this._sourceFileToModuleSource(sourceFile)); + } else { + parentRef = new DeclarationReference(GlobalSource.instance); + } + } if (parentRef === undefined) { return undefined; @@ -108,9 +121,13 @@ export class DeclarationReferenceGenerator { } } - const navigation: Navigation = isTypeMemberOrNonStaticClassMember(symbol) - ? Navigation.Members - : Navigation.Exports; + let navigation: Navigation | 'global' = getNavigationToSymbol(symbol); + if (navigation === 'global') { + if (parentRef.source !== GlobalSource.instance) { + parentRef = new DeclarationReference(GlobalSource.instance); + } + navigation = Navigation.Exports; + } return parentRef .addNavigationStep(navigation, localName) @@ -144,17 +161,64 @@ function isExternalModuleSymbol(symbol: ts.Symbol): boolean { && ts.isSourceFile(symbol.valueDeclaration); } -function isTypeMemberOrNonStaticClassMember(symbol: ts.Symbol): boolean { +function isSameSymbol(left: ts.Symbol | undefined, right: ts.Symbol): boolean { + return left === right + || !!(left && left.valueDeclaration && right.valueDeclaration && left.valueDeclaration === right.valueDeclaration); +} + +function getNavigationToSymbol(symbol: ts.Symbol): Navigation | 'global' { + const parent: ts.Symbol | undefined = TypeScriptInternals.getSymbolParent(symbol); + // First, try to determine navigation to symbol via its parent. + if (parent) { + if (parent.exports && isSameSymbol(parent.exports.get(symbol.escapedName), symbol)) { + return Navigation.Exports; + } + if (parent.members && isSameSymbol(parent.members.get(symbol.escapedName), symbol)) { + return Navigation.Members; + } + if (parent.globalExports && isSameSymbol(parent.globalExports.get(symbol.escapedName), symbol)) { + return 'global'; + } + } + + // Next, try determining navigation to symbol by its node if (symbol.valueDeclaration) { - if (ts.isClassLike(symbol.valueDeclaration.parent)) { - return ts.isClassElement(symbol.valueDeclaration) - && !(ts.getCombinedModifierFlags(symbol.valueDeclaration) & ts.ModifierFlags.Static); + const declaration: ts.Declaration = ts.isBindingElement(symbol.valueDeclaration) + ? ts.walkUpBindingElementsAndPatterns(symbol.valueDeclaration) + : symbol.valueDeclaration; + if (ts.isClassElement(declaration) && ts.isClassLike(declaration.parent)) { + // class members are an "export" if they have the static modifier. + return ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Static + ? Navigation.Exports + : Navigation.Members; + } + if (ts.isTypeElement(declaration) || ts.isObjectLiteralElement(declaration)) { + // type and object literal element members are just members + return Navigation.Members; + } + if (ts.isEnumMember(declaration)) { + // enum members are exports + return Navigation.Exports; + } + if (ts.isExportSpecifier(declaration) + || ts.isExportAssignment(declaration) + || ts.isExportSpecifier(declaration) + || ts.isExportDeclaration(declaration) + || ts.isNamedExports(declaration) + ) { + return Navigation.Exports; + } + // declarations are exports if they have an `export` modifier. + if (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) { + return Navigation.Exports; } - if (ts.isInterfaceDeclaration(symbol.valueDeclaration.parent)) { - return ts.isTypeElement(symbol.valueDeclaration); + if (ts.isSourceFile(declaration.parent) && !ts.isExternalModule(declaration.parent)) { + // declarations in a source file are global if the source file is not a module. + return 'global'; } } - return false; + // all other declarations are locals + return Navigation.Locals; } function getMeaningOfSymbol(symbol: ts.Symbol, meaning: ts.SymbolFlags): Meaning | undefined { diff --git a/build-tests/api-documenter-test/etc/api-documenter-test.api.json b/build-tests/api-documenter-test/etc/api-documenter-test.api.json index c66889f1b1e..e31fdfaec9a 100644 --- a/build-tests/api-documenter-test/etc/api-documenter-test.api.json +++ b/build-tests/api-documenter-test/etc/api-documenter-test.api.json @@ -1540,8 +1540,7 @@ }, { "kind": "Reference", - "text": "T", - "canonicalReference": "T" + "text": "T" }, { "kind": "Content", @@ -1549,8 +1548,7 @@ }, { "kind": "Reference", - "text": "T", - "canonicalReference": "T" + "text": "T" }, { "kind": "Content", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf/api-extractor-scenarios.api.json index 1fb627d47d7..ffc12d3899d 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf/api-extractor-scenarios.api.json @@ -83,7 +83,7 @@ { "kind": "Reference", "text": "ForgottenExport", - "canonicalReference": "!ForgottenExport:class" + "canonicalReference": "api-extractor-scenarios!~ForgottenExport:class" }, { "kind": "Content", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/typeParameters/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/typeParameters/api-extractor-scenarios.api.json index 693d39328aa..189423755b5 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/typeParameters/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/typeParameters/api-extractor-scenarios.api.json @@ -367,8 +367,7 @@ }, { "kind": "Reference", - "text": "T", - "canonicalReference": "T" + "text": "T" }, { "kind": "Content", @@ -506,8 +505,7 @@ }, { "kind": "Reference", - "text": "T", - "canonicalReference": "T" + "text": "T" }, { "kind": "Content", From 86674a281ec80fd86cd368f67a9a3cdeabeaab1e Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sat, 7 Sep 2019 15:16:53 -0700 Subject: [PATCH 4/8] Remove yaml references for type params and toJSON/fromJSON from ExcerptToken --- .../src/documenters/YamlDocumenter.ts | 136 ++++++++---------- .../api-documenter-test/idocinterface6.yml | 1 - common/reviews/api/api-extractor-model.api.md | 6 +- 3 files changed, 58 insertions(+), 85 deletions(-) diff --git a/apps/api-documenter/src/documenters/YamlDocumenter.ts b/apps/api-documenter/src/documenters/YamlDocumenter.ts index c52f732314a..0826198fa1b 100644 --- a/apps/api-documenter/src/documenters/YamlDocumenter.ts +++ b/apps/api-documenter/src/documenters/YamlDocumenter.ts @@ -63,6 +63,7 @@ const yamlApiSchema: JsonSchema = JsonSchema.fromFile(path.join(__dirname, '..', interface IYamlReferences { references: IYamlReference[]; typeNameToUid: Map; + uidTypeReferenceCounters: Map; } /** @@ -73,9 +74,7 @@ export class YamlDocumenter { private readonly _markdownEmitter: CustomMarkdownEmitter; private _apiItemsByCanonicalReference: Map; - private _knownTypeParameters: Set | undefined; private _yamlReferences: IYamlReferences | undefined; - private _uidTypeReferenceCounters: Map; private _outputFolder: string; @@ -83,7 +82,6 @@ export class YamlDocumenter { this._apiModel = apiModel; this._markdownEmitter = new CustomMarkdownEmitter(this._apiModel); this._apiItemsByCanonicalReference = new Map(); - this._uidTypeReferenceCounters = new Map(); this._initApiItems(); } @@ -118,94 +116,78 @@ export class YamlDocumenter { } private _visitApiItems(apiItem: ApiDocumentedItem, parentYamlFile: IYamlApiFile | undefined): boolean { - const savedKnownTypeParameters: Set | undefined = this._knownTypeParameters; - try { - // Track type parameters declared by a declaration so that we do not resolve them - // when looking up types in _linkToUidIfPossible() - if (ApiTypeParameterListMixin.isBaseClassOf(apiItem)) { - this._knownTypeParameters = savedKnownTypeParameters - ? new Set(savedKnownTypeParameters) - : new Set(); - for (const typeParameter of apiItem.typeParameters) { - this._knownTypeParameters.add(typeParameter.name); - } - } + const yamlItem: IYamlItem | undefined = this._generateYamlItem(apiItem); + if (!yamlItem) { + return false; + } - const yamlItem: IYamlItem | undefined = this._generateYamlItem(apiItem); - if (!yamlItem) { - return false; - } + this.onCustomizeYamlItem(yamlItem); - this.onCustomizeYamlItem(yamlItem); + if (this._shouldEmbed(apiItem.kind)) { + if (!parentYamlFile) { + throw new InternalError('Missing file context'); + } + parentYamlFile.items.push(yamlItem); + } else { + const newYamlFile: IYamlApiFile = { + items: [] + }; + newYamlFile.items.push(yamlItem); - if (this._shouldEmbed(apiItem.kind)) { - if (!parentYamlFile) { - throw new InternalError('Missing file context'); - } - parentYamlFile.items.push(yamlItem); + let children: ReadonlyArray; + if (apiItem.kind === ApiItemKind.Package) { + // Skip over the entry point, since it's not part of the documentation hierarchy + children = apiItem.members[0].members; } else { - const newYamlFile: IYamlApiFile = { - items: [] - }; - newYamlFile.items.push(yamlItem); - - let children: ReadonlyArray; - if (apiItem.kind === ApiItemKind.Package) { - // Skip over the entry point, since it's not part of the documentation hierarchy - children = apiItem.members[0].members; - } else { - children = apiItem.members; - } + children = apiItem.members; + } - const flattenedChildren: ApiItem[] = this._flattenNamespaces(children); + const flattenedChildren: ApiItem[] = this._flattenNamespaces(children); - for (const child of flattenedChildren) { - if (child instanceof ApiDocumentedItem) { - if (this._visitApiItems(child, newYamlFile)) { - if (!yamlItem.children) { - yamlItem.children = []; - } - yamlItem.children.push(this._getUid(child)); + for (const child of flattenedChildren) { + if (child instanceof ApiDocumentedItem) { + if (this._visitApiItems(child, newYamlFile)) { + if (!yamlItem.children) { + yamlItem.children = []; } + yamlItem.children.push(this._getUid(child)); } } + } - if (this._yamlReferences) { - if (this._yamlReferences.references.length > 0) { - if (newYamlFile.references) { - newYamlFile.references = [...newYamlFile.references, ...this._yamlReferences.references]; - } else { - newYamlFile.references = this._yamlReferences.references; - } + if (this._yamlReferences) { + if (this._yamlReferences.references.length > 0) { + if (newYamlFile.references) { + newYamlFile.references = [...newYamlFile.references, ...this._yamlReferences.references]; + } else { + newYamlFile.references = this._yamlReferences.references; } - this._yamlReferences = undefined; } + this._yamlReferences = undefined; + } - const yamlFilePath: string = this._getYamlFilePath(apiItem); + const yamlFilePath: string = this._getYamlFilePath(apiItem); - if (apiItem.kind === ApiItemKind.Package) { - console.log('Writing ' + yamlFilePath); - } + if (apiItem.kind === ApiItemKind.Package) { + console.log('Writing ' + yamlFilePath); + } - this._writeYamlFile(newYamlFile, yamlFilePath, 'UniversalReference', yamlApiSchema); + this._writeYamlFile(newYamlFile, yamlFilePath, 'UniversalReference', yamlApiSchema); - if (parentYamlFile) { - if (!parentYamlFile.references) { - parentYamlFile.references = []; - } + if (parentYamlFile) { + if (!parentYamlFile.references) { + parentYamlFile.references = []; + } - parentYamlFile.references.push({ - uid: this._getUid(apiItem), - name: this._getYamlItemName(apiItem) - }); + parentYamlFile.references.push({ + uid: this._getUid(apiItem), + name: this._getYamlItemName(apiItem) + }); - } } - - return true; - } finally { - this._knownTypeParameters = savedKnownTypeParameters; } + + return true; } // Since the YAML schema does not yet support nested namespaces, we simply omit them from @@ -636,7 +618,8 @@ export class YamlDocumenter { if (!this._yamlReferences) { this._yamlReferences = { references: [], - typeNameToUid: new Map() + typeNameToUid: new Map(), + uidTypeReferenceCounters: new Map() }; } return this._yamlReferences; @@ -662,11 +645,6 @@ export class YamlDocumenter { const typeName: string = typeExcerpt.text.trim(); - // Record a reference to a type parameter as its name, so as not to resolve to a conflicting name - if (this._knownTypeParameters && this._knownTypeParameters.has(typeName)) { - return this._recordYamlReference(this._ensureYamlReferences(), typeName, typeName); - } - // If there are no references to be used for a complex type, return the type name. if (!excerptTokens.some(tok => tok.kind === ExcerptTokenKind.Reference && !!tok.canonicalReference)) { return typeName; @@ -700,8 +678,8 @@ export class YamlDocumenter { // Keep track of the count for the base uid (without meaning or overload index) to ensure // that each complex type reference is unique. - const counter: number = this._uidTypeReferenceCounters.get(baseUid) || 0; - this._uidTypeReferenceCounters.set(baseUid, counter + 1); + const counter: number = yamlReferences.uidTypeReferenceCounters.get(baseUid) || 0; + yamlReferences.uidTypeReferenceCounters.set(baseUid, counter + 1); const uid: string = contextUid .addNavigationStep(Navigation.Locals, `${counter}`) diff --git a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface6.yml b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface6.yml index 8b84d736d5a..c52c45fcee5 100644 --- a/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface6.yml +++ b/build-tests/api-documenter-test/etc/yaml/api-documenter-test/idocinterface6.yml @@ -112,7 +112,6 @@ references: fullName: IDocInterface1 - name: '[]' fullName: '[]' - - uid: T - uid: 'api-documenter-test!IDocInterface6#intersectionProperty~0:complex' name: IDocInterface1 & IDocInterface2 fullName: IDocInterface1 & IDocInterface2 diff --git a/common/reviews/api/api-extractor-model.api.md b/common/reviews/api/api-extractor-model.api.md index 8e30a99730a..2e4ac027605 100644 --- a/common/reviews/api/api-extractor-model.api.md +++ b/common/reviews/api/api-extractor-model.api.md @@ -617,14 +617,10 @@ export class ExcerptToken { // (undocumented) readonly canonicalReference: DeclarationReference | undefined; // (undocumented) - static fromJSON(object: IExcerptToken): ExcerptToken; - // (undocumented) readonly kind: ExcerptTokenKind; // (undocumented) readonly text: string; - // (undocumented) - toJSON(): IExcerptToken; -} + } // @public (undocumented) export const enum ExcerptTokenKind { From 4b881d917aa96e75deae7f8ae33a661d067b3d7f Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 8 Sep 2019 13:08:15 -0700 Subject: [PATCH 5/8] Add a unit test for typeof applied to a function --- .../config/build-config.json | 1 + .../typeOf2/api-extractor-scenarios.api.json | 133 ++++++++++++++++++ .../typeOf2/api-extractor-scenarios.api.md | 18 +++ .../etc/test-outputs/typeOf2/rollup.d.ts | 10 ++ .../src/typeOf2/index.ts | 12 ++ 5 files changed, 174 insertions(+) create mode 100644 build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/api-extractor-scenarios.api.json create mode 100644 build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/api-extractor-scenarios.api.md create mode 100644 build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/rollup.d.ts create mode 100644 build-tests/api-extractor-scenarios/src/typeOf2/index.ts diff --git a/build-tests/api-extractor-scenarios/config/build-config.json b/build-tests/api-extractor-scenarios/config/build-config.json index d2e0069eba4..4c0f15f3299 100644 --- a/build-tests/api-extractor-scenarios/config/build-config.json +++ b/build-tests/api-extractor-scenarios/config/build-config.json @@ -22,6 +22,7 @@ "inconsistentReleaseTags", "preapproved", "typeOf", + "typeOf2", "typeParameters" ] } diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/api-extractor-scenarios.api.json new file mode 100644 index 00000000000..643190bc47f --- /dev/null +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/api-extractor-scenarios.api.json @@ -0,0 +1,133 @@ +{ + "metadata": { + "toolPackage": "@microsoft/api-extractor", + "toolVersion": "[test mode]", + "schemaVersion": 1003, + "oldestForwardsCompatibleVersion": 1001 + }, + "kind": "Package", + "canonicalReference": "api-extractor-scenarios!", + "docComment": "", + "name": "api-extractor-scenarios", + "members": [ + { + "kind": "EntryPoint", + "canonicalReference": "api-extractor-scenarios!", + "name": "", + "members": [ + { + "kind": "Function", + "canonicalReference": "api-extractor-scenarios!f:function(1)", + "docComment": "/**\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export declare function " + }, + { + "kind": "Reference", + "text": "f" + }, + { + "kind": "Content", + "text": "(): " + }, + { + "kind": "Content", + "text": "{\n " + }, + { + "kind": "Reference", + "text": "a" + }, + { + "kind": "Content", + "text": ": number;\n}" + }, + { + "kind": "Content", + "text": ";" + } + ], + "returnTypeTokenRange": { + "startIndex": 3, + "endIndex": 6 + }, + "releaseTag": "Public", + "overloadIndex": 1, + "parameters": [], + "name": "f" + }, + { + "kind": "Function", + "canonicalReference": "api-extractor-scenarios!g:function(1)", + "docComment": "/**\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export declare function " + }, + { + "kind": "Reference", + "text": "g" + }, + { + "kind": "Content", + "text": "(" + }, + { + "kind": "Reference", + "text": "callback" + }, + { + "kind": "Content", + "text": ": " + }, + { + "kind": "Content", + "text": "typeof " + }, + { + "kind": "Reference", + "text": "f", + "canonicalReference": "api-extractor-scenarios!f:function" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "typeof " + }, + { + "kind": "Reference", + "text": "f", + "canonicalReference": "api-extractor-scenarios!f:function" + }, + { + "kind": "Content", + "text": ";" + } + ], + "returnTypeTokenRange": { + "startIndex": 8, + "endIndex": 10 + }, + "releaseTag": "Public", + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "callback", + "parameterTypeTokenRange": { + "startIndex": 5, + "endIndex": 7 + } + } + ], + "name": "g" + } + ] + } + ] +} diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/api-extractor-scenarios.api.md b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/api-extractor-scenarios.api.md new file mode 100644 index 00000000000..26384c3e2a4 --- /dev/null +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/api-extractor-scenarios.api.md @@ -0,0 +1,18 @@ +## API Report File for "api-extractor-scenarios" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +// @public (undocumented) +export function f(): { + a: number; +}; + +// @public (undocumented) +export function g(callback: typeof f): typeof f; + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/rollup.d.ts b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/rollup.d.ts new file mode 100644 index 00000000000..32b7b7dbf14 --- /dev/null +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/rollup.d.ts @@ -0,0 +1,10 @@ + +/** @public */ +export declare function f(): { + a: number; +}; + +/** @public */ +export declare function g(callback: typeof f): typeof f; + +export { } diff --git a/build-tests/api-extractor-scenarios/src/typeOf2/index.ts b/build-tests/api-extractor-scenarios/src/typeOf2/index.ts new file mode 100644 index 00000000000..07728912e65 --- /dev/null +++ b/build-tests/api-extractor-scenarios/src/typeOf2/index.ts @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +/** @public */ +export function f(): { a: number } { + return { a: 1}; +} + +/** @public */ +export function g(callback: typeof f): typeof f { + return callback; +} From a2e45837f7971fef351acf943afebab77b48b3f6 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 8 Sep 2019 13:14:40 -0700 Subject: [PATCH 6/8] Create a ExcerptTokenKind.Reference node /only/ if the canonicalReference exists --- apps/api-extractor/src/generators/ExcerptBuilder.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/api-extractor/src/generators/ExcerptBuilder.ts b/apps/api-extractor/src/generators/ExcerptBuilder.ts index ce71e902a8f..2ce3784cdcd 100644 --- a/apps/api-extractor/src/generators/ExcerptBuilder.ts +++ b/apps/api-extractor/src/generators/ExcerptBuilder.ts @@ -117,11 +117,16 @@ export class ExcerptBuilder { } if (span.prefix) { + let canonicalReference: DeclarationReference | undefined = undefined; + if (span.kind === ts.SyntaxKind.Identifier) { const name: ts.Identifier = span.node as ts.Identifier; - const canonicalReference: DeclarationReference | undefined = isDeclarationName(name) - ? undefined - : state.referenceGenerator.getDeclarationReferenceForIdentifier(name); + if (!isDeclarationName(name)) { + canonicalReference = state.referenceGenerator.getDeclarationReferenceForIdentifier(name); + } + } + + if (canonicalReference) { ExcerptBuilder._appendToken(excerptTokens, ExcerptTokenKind.Reference, span.prefix, state, canonicalReference); } else { From 585184975a21435ca9a88410f7b03b05e64ab097 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 8 Sep 2019 13:14:49 -0700 Subject: [PATCH 7/8] rush build --- .../etc/api-documenter-test.api.json | 704 ++++-------------- .../api-extractor-scenarios.api.json | 40 +- .../api-extractor-scenarios.api.json | 264 ++----- .../api-extractor-scenarios.api.json | 50 +- .../api-extractor-scenarios.api.json | 70 +- .../api-extractor-scenarios.api.json | 10 +- .../api-extractor-scenarios.api.json | 10 +- .../api-extractor-scenarios.api.json | 14 +- .../api-extractor-scenarios.api.json | 10 +- .../api-extractor-scenarios.api.json | 98 +-- .../api-extractor-scenarios.api.json | 90 +-- .../api-extractor-scenarios.api.json | 92 +-- .../api-extractor-scenarios.api.json | 10 +- .../api-extractor-scenarios.api.json | 20 +- .../api-extractor-scenarios.api.json | 30 +- .../api-extractor-scenarios.api.json | 10 +- .../api-extractor-scenarios.api.json | 10 +- .../api-extractor-scenarios.api.json | 18 +- .../api-extractor-scenarios.api.json | 34 +- .../typeOf/api-extractor-scenarios.api.json | 28 +- .../typeOf2/api-extractor-scenarios.api.json | 50 +- .../api-extractor-scenarios.api.json | 200 +---- 22 files changed, 373 insertions(+), 1489 deletions(-) diff --git a/build-tests/api-documenter-test/etc/api-documenter-test.api.json b/build-tests/api-documenter-test/etc/api-documenter-test.api.json index e31fdfaec9a..f90d0628ef4 100644 --- a/build-tests/api-documenter-test/etc/api-documenter-test.api.json +++ b/build-tests/api-documenter-test/etc/api-documenter-test.api.json @@ -20,13 +20,9 @@ "canonicalReference": "api-documenter-test!constVariable:var", "docComment": "/**\n * An exported variable declaration.\n *\n * @public\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "constVariable" - }, { "kind": "Content", - "text": ": " + "text": "constVariable: " }, { "kind": "Content", @@ -36,8 +32,8 @@ "releaseTag": "Public", "name": "constVariable", "variableTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } }, { @@ -47,15 +43,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "DocBaseClass" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class DocBaseClass " } ], "releaseTag": "Public", @@ -82,15 +70,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "constructor(" - }, - { - "kind": "Reference", - "text": "x" - }, - { - "kind": "Content", - "text": ": " + "text": "constructor(x: " }, { "kind": "Content", @@ -107,8 +87,8 @@ { "parameterName": "x", "parameterTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 } } ] @@ -123,15 +103,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "DocClass1" - }, - { - "kind": "Content", - "text": " extends " + "text": "export declare class DocClass1 extends " }, { "kind": "Reference", @@ -173,13 +145,9 @@ "canonicalReference": "api-documenter-test!DocClass1#deprecatedExample:member(1)", "docComment": "/**\n * @deprecated\n *\n * Use `otherThing()` instead.\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "deprecatedExample" - }, { "kind": "Content", - "text": "(): " + "text": "deprecatedExample(): " }, { "kind": "Content", @@ -192,8 +160,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -205,21 +173,9 @@ "canonicalReference": "api-documenter-test!DocClass1#exampleFunction:member(1)", "docComment": "/**\n * This is an overloaded function.\n *\n * @param a - the first string\n *\n * @param b - the second string\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "exampleFunction" - }, - { - "kind": "Content", - "text": "(" - }, - { - "kind": "Reference", - "text": "a" - }, { "kind": "Content", - "text": ": " + "text": "exampleFunction(a: " }, { "kind": "Content", @@ -227,15 +183,7 @@ }, { "kind": "Content", - "text": ", " - }, - { - "kind": "Reference", - "text": "b" - }, - { - "kind": "Content", - "text": ": " + "text": ", b: " }, { "kind": "Content", @@ -256,8 +204,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 10, - "endIndex": 11 + "startIndex": 5, + "endIndex": 6 }, "releaseTag": "Public", "overloadIndex": 1, @@ -265,15 +213,15 @@ { "parameterName": "a", "parameterTypeTokenRange": { - "startIndex": 4, - "endIndex": 5 + "startIndex": 1, + "endIndex": 2 } }, { "parameterName": "b", "parameterTypeTokenRange": { - "startIndex": 8, - "endIndex": 9 + "startIndex": 3, + "endIndex": 4 } } ], @@ -284,21 +232,9 @@ "canonicalReference": "api-documenter-test!DocClass1#exampleFunction:member(2)", "docComment": "/**\n * This is also an overloaded function.\n *\n * @param x - the number\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "exampleFunction" - }, - { - "kind": "Content", - "text": "(" - }, - { - "kind": "Reference", - "text": "x" - }, { "kind": "Content", - "text": ": " + "text": "exampleFunction(x: " }, { "kind": "Content", @@ -319,8 +255,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 6, - "endIndex": 7 + "startIndex": 3, + "endIndex": 4 }, "releaseTag": "Public", "overloadIndex": 2, @@ -328,8 +264,8 @@ { "parameterName": "x", "parameterTypeTokenRange": { - "startIndex": 4, - "endIndex": 5 + "startIndex": 1, + "endIndex": 2 } } ], @@ -340,13 +276,9 @@ "canonicalReference": "api-documenter-test!DocClass1#interestingEdgeCases:member(1)", "docComment": "/**\n * Example: \"\\{ \\\\\"maxItemsToShow\\\\\": 123 \\}\"\n *\n * The regular expression used to validate the constraints is /^[a-zA-Z0-9\\\\-_]+$/\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "interestingEdgeCases" - }, { "kind": "Content", - "text": "(): " + "text": "interestingEdgeCases(): " }, { "kind": "Content", @@ -359,8 +291,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -372,13 +304,9 @@ "canonicalReference": "api-documenter-test!DocClass1#malformedEvent:member", "docComment": "/**\n * This event should have been marked as readonly.\n *\n * @eventProperty\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "malformedEvent" - }, { "kind": "Content", - "text": ": " + "text": "malformedEvent: " }, { "kind": "Reference", @@ -393,8 +321,8 @@ "releaseTag": "Public", "name": "malformedEvent", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "isStatic": false }, @@ -405,15 +333,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "readonly " - }, - { - "kind": "Reference", - "text": "modifiedEvent" - }, - { - "kind": "Content", - "text": ": " + "text": "readonly modifiedEvent: " }, { "kind": "Reference", @@ -428,8 +348,8 @@ "releaseTag": "Public", "name": "modifiedEvent", "propertyTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 }, "isStatic": false }, @@ -438,13 +358,9 @@ "canonicalReference": "api-documenter-test!DocClass1#regularProperty:member", "docComment": "/**\n * This is a regular property that happens to use the SystemEvent type.\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "regularProperty" - }, { "kind": "Content", - "text": ": " + "text": "regularProperty: " }, { "kind": "Reference", @@ -459,8 +375,8 @@ "releaseTag": "Public", "name": "regularProperty", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "isStatic": false }, @@ -471,23 +387,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "static " - }, - { - "kind": "Reference", - "text": "sumWithExample" - }, - { - "kind": "Content", - "text": "(" - }, - { - "kind": "Reference", - "text": "x" - }, - { - "kind": "Content", - "text": ": " + "text": "static sumWithExample(x: " }, { "kind": "Content", @@ -495,15 +395,7 @@ }, { "kind": "Content", - "text": ", " - }, - { - "kind": "Reference", - "text": "y" - }, - { - "kind": "Content", - "text": ": " + "text": ", y: " }, { "kind": "Content", @@ -524,8 +416,8 @@ ], "isStatic": true, "returnTypeTokenRange": { - "startIndex": 11, - "endIndex": 12 + "startIndex": 5, + "endIndex": 6 }, "releaseTag": "Public", "overloadIndex": 1, @@ -533,15 +425,15 @@ { "parameterName": "x", "parameterTypeTokenRange": { - "startIndex": 5, - "endIndex": 6 + "startIndex": 1, + "endIndex": 2 } }, { "parameterName": "y", "parameterTypeTokenRange": { - "startIndex": 9, - "endIndex": 10 + "startIndex": 3, + "endIndex": 4 } } ], @@ -552,13 +444,9 @@ "canonicalReference": "api-documenter-test!DocClass1#tableExample:member(1)", "docComment": "/**\n * An example with tables:\n *\n * @remarks\n *\n *
John Doe
\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "tableExample" - }, { "kind": "Content", - "text": "(): " + "text": "tableExample(): " }, { "kind": "Content", @@ -571,8 +459,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -581,17 +469,17 @@ } ], "extendsTokenRange": { - "startIndex": 3, - "endIndex": 5 + "startIndex": 1, + "endIndex": 3 }, "implementsTokenRanges": [ { - "startIndex": 6, - "endIndex": 7 + "startIndex": 4, + "endIndex": 5 }, { - "startIndex": 8, - "endIndex": 10 + "startIndex": 6, + "endIndex": 8 } ] }, @@ -602,15 +490,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare enum " - }, - { - "kind": "Reference", - "text": "DocEnum" - }, - { - "kind": "Content", - "text": " " + "text": "export declare enum DocEnum " } ], "releaseTag": "Public", @@ -621,13 +501,9 @@ "canonicalReference": "api-documenter-test!DocEnum.One:member", "docComment": "/**\n * These are some docs for One\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "One" - }, { "kind": "Content", - "text": " = " + "text": "One = " }, { "kind": "Content", @@ -637,8 +513,8 @@ "releaseTag": "Public", "name": "One", "initializerTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } }, { @@ -646,13 +522,9 @@ "canonicalReference": "api-documenter-test!DocEnum.Two:member", "docComment": "/**\n * These are some docs for Two\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "Two" - }, { "kind": "Content", - "text": " = " + "text": "Two = " }, { "kind": "Content", @@ -662,8 +534,8 @@ "releaseTag": "Public", "name": "Two", "initializerTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } }, { @@ -671,13 +543,9 @@ "canonicalReference": "api-documenter-test!DocEnum.Zero:member", "docComment": "/**\n * These are some docs for Zero\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "Zero" - }, { "kind": "Content", - "text": " = " + "text": "Zero = " }, { "kind": "Content", @@ -687,8 +555,8 @@ "releaseTag": "Public", "name": "Zero", "initializerTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ] @@ -700,15 +568,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare namespace " - }, - { - "kind": "Reference", - "text": "EcmaSmbols" - }, - { - "kind": "Content", - "text": " " + "text": "export declare namespace EcmaSmbols " } ], "releaseTag": "Public", @@ -719,13 +579,9 @@ "canonicalReference": "api-documenter-test!EcmaSmbols.example:var", "docComment": "/**\n * An ECMAScript symbol\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "example" - }, { "kind": "Content", - "text": ": " + "text": "example: " }, { "kind": "Content", @@ -735,8 +591,8 @@ "releaseTag": "Public", "name": "example", "variableTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ] @@ -748,15 +604,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare type " - }, - { - "kind": "Reference", - "text": "ExampleTypeAlias" - }, - { - "kind": "Content", - "text": " = " + "text": "export declare type ExampleTypeAlias = " }, { "kind": "Reference", @@ -775,8 +623,8 @@ "releaseTag": "Public", "name": "ExampleTypeAlias", "typeTokenRange": { - "startIndex": 3, - "endIndex": 5 + "startIndex": 1, + "endIndex": 3 } }, { @@ -786,23 +634,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "Generic" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "T" - }, - { - "kind": "Content", - "text": "> " + "text": "export declare class Generic " } ], "releaseTag": "Public", @@ -830,23 +662,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "globalFunction" - }, - { - "kind": "Content", - "text": "(" - }, - { - "kind": "Reference", - "text": "x" - }, - { - "kind": "Content", - "text": ": " + "text": "export declare function globalFunction(x: " }, { "kind": "Content", @@ -866,8 +682,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 7, - "endIndex": 8 + "startIndex": 3, + "endIndex": 4 }, "releaseTag": "Public", "overloadIndex": 1, @@ -875,8 +691,8 @@ { "parameterName": "x", "parameterTypeTokenRange": { - "startIndex": 5, - "endIndex": 6 + "startIndex": 1, + "endIndex": 2 } } ], @@ -889,15 +705,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export interface " - }, - { - "kind": "Reference", - "text": "IDocInterface1" - }, - { - "kind": "Content", - "text": " " + "text": "export interface IDocInterface1 " } ], "releaseTag": "Public", @@ -908,13 +716,9 @@ "canonicalReference": "api-documenter-test!IDocInterface1#regularProperty:member", "docComment": "/**\n * Does something\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "regularProperty" - }, { "kind": "Content", - "text": ": " + "text": "regularProperty: " }, { "kind": "Reference", @@ -929,8 +733,8 @@ "releaseTag": "Public", "name": "regularProperty", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ], @@ -943,15 +747,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export interface " - }, - { - "kind": "Reference", - "text": "IDocInterface2" - }, - { - "kind": "Content", - "text": " extends " + "text": "export interface IDocInterface2 extends " }, { "kind": "Reference", @@ -971,13 +767,9 @@ "canonicalReference": "api-documenter-test!IDocInterface2#deprecatedExample:member(1)", "docComment": "/**\n * @deprecated\n *\n * Use `otherThing()` instead.\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "deprecatedExample" - }, { "kind": "Content", - "text": "(): " + "text": "deprecatedExample(): " }, { "kind": "Content", @@ -989,8 +781,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -1000,8 +792,8 @@ ], "extendsTokenRanges": [ { - "startIndex": 3, - "endIndex": 5 + "startIndex": 1, + "endIndex": 3 } ] }, @@ -1012,15 +804,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export interface " - }, - { - "kind": "Reference", - "text": "IDocInterface3" - }, - { - "kind": "Content", - "text": " " + "text": "export interface IDocInterface3 " } ], "releaseTag": "Public", @@ -1092,15 +876,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "(" - }, - { - "kind": "Reference", - "text": "x" - }, - { - "kind": "Content", - "text": ": " + "text": "(x: " }, { "kind": "Content", @@ -1120,8 +896,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 5, - "endIndex": 6 + "startIndex": 3, + "endIndex": 4 }, "releaseTag": "Public", "overloadIndex": 1, @@ -1129,8 +905,8 @@ { "parameterName": "x", "parameterTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 } } ] @@ -1169,15 +945,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "[" - }, - { - "kind": "Reference", - "text": "x" - }, - { - "kind": "Content", - "text": ": " + "text": "[x: " }, { "kind": "Content", @@ -1197,8 +965,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 5, - "endIndex": 6 + "startIndex": 3, + "endIndex": 4 }, "releaseTag": "Public", "overloadIndex": 1, @@ -1206,8 +974,8 @@ { "parameterName": "x", "parameterTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 } } ] @@ -1247,15 +1015,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export interface " - }, - { - "kind": "Reference", - "text": "IDocInterface4" - }, - { - "kind": "Content", - "text": " " + "text": "export interface IDocInterface4 " } ], "releaseTag": "Public", @@ -1266,33 +1026,13 @@ "canonicalReference": "api-documenter-test!IDocInterface4#Context:member", "docComment": "/**\n * Test newline rendering when code blocks are used in tables\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "Context" - }, - { - "kind": "Content", - "text": ": " - }, - { - "kind": "Content", - "text": "({ " - }, - { - "kind": "Reference", - "text": "children" - }, { "kind": "Content", - "text": " }: {\n " - }, - { - "kind": "Reference", - "text": "children" + "text": "Context: " }, { "kind": "Content", - "text": ": string;\n }) => boolean" + "text": "({ children }: {\n children: string;\n }) => boolean" }, { "kind": "Content", @@ -1302,8 +1042,8 @@ "releaseTag": "Public", "name": "Context", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 7 + "startIndex": 1, + "endIndex": 2 } }, { @@ -1311,13 +1051,9 @@ "canonicalReference": "api-documenter-test!IDocInterface4#generic:member", "docComment": "/**\n * make sure html entities are escaped in tables.\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "generic" - }, { "kind": "Content", - "text": ": " + "text": "generic: " }, { "kind": "Reference", @@ -1336,8 +1072,8 @@ "releaseTag": "Public", "name": "generic", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 4 + "startIndex": 1, + "endIndex": 3 } }, { @@ -1345,13 +1081,9 @@ "canonicalReference": "api-documenter-test!IDocInterface4#numberOrFunction:member", "docComment": "/**\n * a union type with a function\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "numberOrFunction" - }, { "kind": "Content", - "text": ": " + "text": "numberOrFunction: " }, { "kind": "Content", @@ -1365,8 +1097,8 @@ "releaseTag": "Public", "name": "numberOrFunction", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } }, { @@ -1374,13 +1106,9 @@ "canonicalReference": "api-documenter-test!IDocInterface4#stringOrNumber:member", "docComment": "/**\n * a union type\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "stringOrNumber" - }, { "kind": "Content", - "text": ": " + "text": "stringOrNumber: " }, { "kind": "Content", @@ -1394,8 +1122,8 @@ "releaseTag": "Public", "name": "stringOrNumber", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ], @@ -1408,15 +1136,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export interface " - }, - { - "kind": "Reference", - "text": "IDocInterface5" - }, - { - "kind": "Content", - "text": " " + "text": "export interface IDocInterface5 " } ], "releaseTag": "Public", @@ -1427,13 +1147,9 @@ "canonicalReference": "api-documenter-test!IDocInterface5#regularProperty:member", "docComment": "/**\n * Property of type string that does something\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "regularProperty" - }, { "kind": "Content", - "text": ": " + "text": "regularProperty: " }, { "kind": "Content", @@ -1447,8 +1163,8 @@ "releaseTag": "Public", "name": "regularProperty", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ], @@ -1461,15 +1177,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export interface " - }, - { - "kind": "Reference", - "text": "IDocInterface6" - }, - { - "kind": "Content", - "text": " " + "text": "export interface IDocInterface6 " } ], "releaseTag": "Public", @@ -1480,13 +1188,9 @@ "canonicalReference": "api-documenter-test!IDocInterface6#arrayProperty:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "arrayProperty" - }, { "kind": "Content", - "text": ": " + "text": "arrayProperty: " }, { "kind": "Reference", @@ -1505,8 +1209,8 @@ "releaseTag": "Public", "name": "arrayProperty", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 4 + "startIndex": 1, + "endIndex": 3 } }, { @@ -1514,32 +1218,12 @@ "canonicalReference": "api-documenter-test!IDocInterface6#genericReferenceMethod:member(1)", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "genericReferenceMethod" - }, { "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "T" - }, - { - "kind": "Content", - "text": ">(" - }, - { - "kind": "Reference", - "text": "x" + "text": "genericReferenceMethod(x: " }, { "kind": "Content", - "text": ": " - }, - { - "kind": "Reference", "text": "T" }, { @@ -1547,7 +1231,7 @@ "text": "): " }, { - "kind": "Reference", + "kind": "Content", "text": "T" }, { @@ -1556,8 +1240,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 8, - "endIndex": 9 + "startIndex": 3, + "endIndex": 4 }, "releaseTag": "Public", "overloadIndex": 1, @@ -1565,8 +1249,8 @@ { "parameterName": "x", "parameterTypeTokenRange": { - "startIndex": 6, - "endIndex": 7 + "startIndex": 1, + "endIndex": 2 } } ], @@ -1590,13 +1274,9 @@ "canonicalReference": "api-documenter-test!IDocInterface6#intersectionProperty:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "intersectionProperty" - }, { "kind": "Content", - "text": ": " + "text": "intersectionProperty: " }, { "kind": "Reference", @@ -1620,8 +1300,8 @@ "releaseTag": "Public", "name": "intersectionProperty", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 5 + "startIndex": 1, + "endIndex": 4 } }, { @@ -1629,13 +1309,9 @@ "canonicalReference": "api-documenter-test!IDocInterface6#regularProperty:member", "docComment": "/**\n * Property of type number that does something\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "regularProperty" - }, { "kind": "Content", - "text": ": " + "text": "regularProperty: " }, { "kind": "Content", @@ -1649,8 +1325,8 @@ "releaseTag": "Public", "name": "regularProperty", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } }, { @@ -1658,13 +1334,9 @@ "canonicalReference": "api-documenter-test!IDocInterface6#tupleProperty:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "tupleProperty" - }, { "kind": "Content", - "text": ": " + "text": "tupleProperty: " }, { "kind": "Content", @@ -1696,8 +1368,8 @@ "releaseTag": "Public", "name": "tupleProperty", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 7 + "startIndex": 1, + "endIndex": 6 } }, { @@ -1705,13 +1377,9 @@ "canonicalReference": "api-documenter-test!IDocInterface6#typeReferenceProperty:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "typeReferenceProperty" - }, { "kind": "Content", - "text": ": " + "text": "typeReferenceProperty: " }, { "kind": "Reference", @@ -1739,8 +1407,8 @@ "releaseTag": "Public", "name": "typeReferenceProperty", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 6 + "startIndex": 1, + "endIndex": 5 } }, { @@ -1748,13 +1416,9 @@ "canonicalReference": "api-documenter-test!IDocInterface6#unionProperty:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "unionProperty" - }, { "kind": "Content", - "text": ": " + "text": "unionProperty: " }, { "kind": "Reference", @@ -1778,8 +1442,8 @@ "releaseTag": "Public", "name": "unionProperty", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 5 + "startIndex": 1, + "endIndex": 4 } } ], @@ -1792,15 +1456,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare namespace " - }, - { - "kind": "Reference", - "text": "OuterNamespace" - }, - { - "kind": "Content", - "text": " " + "text": "export declare namespace OuterNamespace " } ], "releaseTag": "Public", @@ -1813,15 +1469,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "namespace " - }, - { - "kind": "Reference", - "text": "InnerNamespace" - }, - { - "kind": "Content", - "text": " " + "text": "namespace InnerNamespace " } ], "releaseTag": "Public", @@ -1834,23 +1482,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "function " - }, - { - "kind": "Reference", - "text": "nestedFunction" - }, - { - "kind": "Content", - "text": "(" - }, - { - "kind": "Reference", - "text": "x" - }, - { - "kind": "Content", - "text": ": " + "text": "function nestedFunction(x: " }, { "kind": "Content", @@ -1870,8 +1502,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 7, - "endIndex": 8 + "startIndex": 3, + "endIndex": 4 }, "releaseTag": "Public", "overloadIndex": 1, @@ -1879,8 +1511,8 @@ { "parameterName": "x", "parameterTypeTokenRange": { - "startIndex": 5, - "endIndex": 6 + "startIndex": 1, + "endIndex": 2 } } ], @@ -1893,13 +1525,9 @@ "canonicalReference": "api-documenter-test!OuterNamespace.nestedVariable:var", "docComment": "/**\n * A variable exported from within a namespace.\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "nestedVariable" - }, { "kind": "Content", - "text": ": " + "text": "nestedVariable: " }, { "kind": "Content", @@ -1909,8 +1537,8 @@ "releaseTag": "Public", "name": "nestedVariable", "variableTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ] @@ -1922,15 +1550,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "SystemEvent" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class SystemEvent " } ], "releaseTag": "Public", @@ -1941,21 +1561,9 @@ "canonicalReference": "api-documenter-test!SystemEvent#addHandler:member(1)", "docComment": "/**\n * Adds an handler for the event.\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "addHandler" - }, { "kind": "Content", - "text": "(" - }, - { - "kind": "Reference", - "text": "handler" - }, - { - "kind": "Content", - "text": ": " + "text": "addHandler(handler: " }, { "kind": "Content", @@ -1976,8 +1584,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 6, - "endIndex": 7 + "startIndex": 3, + "endIndex": 4 }, "releaseTag": "Public", "overloadIndex": 1, @@ -1985,8 +1593,8 @@ { "parameterName": "handler", "parameterTypeTokenRange": { - "startIndex": 4, - "endIndex": 5 + "startIndex": 1, + "endIndex": 2 } } ], diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/ambientNameConflict/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/ambientNameConflict/api-extractor-scenarios.api.json index a74b19ed394..655d30ae318 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/ambientNameConflict/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/ambientNameConflict/api-extractor-scenarios.api.json @@ -22,23 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "ambientNameConflict" - }, - { - "kind": "Content", - "text": "(" - }, - { - "kind": "Reference", - "text": "p1" - }, - { - "kind": "Content", - "text": ": " + "text": "export declare function ambientNameConflict(p1: " }, { "kind": "Reference", @@ -51,15 +35,7 @@ }, { "kind": "Content", - "text": ", " - }, - { - "kind": "Reference", - "text": "p2" - }, - { - "kind": "Content", - "text": ": " + "text": ", p2: " }, { "kind": "Reference", @@ -84,8 +60,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 13, - "endIndex": 14 + "startIndex": 7, + "endIndex": 8 }, "releaseTag": "Public", "overloadIndex": 1, @@ -93,15 +69,15 @@ { "parameterName": "p1", "parameterTypeTokenRange": { - "startIndex": 5, - "endIndex": 7 + "startIndex": 1, + "endIndex": 3 } }, { "parameterName": "p2", "parameterTypeTokenRange": { - "startIndex": 10, - "endIndex": 12 + "startIndex": 4, + "endIndex": 6 } } ], diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/apiItemKinds/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/apiItemKinds/api-extractor-scenarios.api.json index 017fc128235..46c907a96ab 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/apiItemKinds/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/apiItemKinds/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare abstract class " - }, - { - "kind": "Reference", - "text": "AbstractClass" - }, - { - "kind": "Content", - "text": " " + "text": "export declare abstract class AbstractClass " } ], "releaseTag": "Public", @@ -43,15 +35,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "abstract " - }, - { - "kind": "Reference", - "text": "member" - }, - { - "kind": "Content", - "text": "(): " + "text": "abstract member(): " }, { "kind": "Content", @@ -64,8 +48,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -82,15 +66,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "ClassWithTypeLiterals" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class ClassWithTypeLiterals " } ], "releaseTag": "Public", @@ -101,41 +77,13 @@ "canonicalReference": "api-extractor-scenarios!ClassWithTypeLiterals#method1:member(1)", "docComment": "/**\n * type literal in\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "method1" - }, { "kind": "Content", - "text": "(" - }, - { - "kind": "Reference", - "text": "vector" + "text": "method1(vector: " }, { "kind": "Content", - "text": ": " - }, - { - "kind": "Content", - "text": "{\n " - }, - { - "kind": "Reference", - "text": "x" - }, - { - "kind": "Content", - "text": ": number;\n " - }, - { - "kind": "Reference", - "text": "y" - }, - { - "kind": "Content", - "text": ": number;\n }" + "text": "{\n x: number;\n y: number;\n }" }, { "kind": "Content", @@ -152,8 +100,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 10, - "endIndex": 11 + "startIndex": 3, + "endIndex": 4 }, "releaseTag": "Public", "overloadIndex": 1, @@ -161,8 +109,8 @@ { "parameterName": "vector", "parameterTypeTokenRange": { - "startIndex": 4, - "endIndex": 9 + "startIndex": 1, + "endIndex": 2 } } ], @@ -173,25 +121,13 @@ "canonicalReference": "api-extractor-scenarios!ClassWithTypeLiterals#method2:member(1)", "docComment": "/**\n * type literal output\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "method2" - }, - { - "kind": "Content", - "text": "(): " - }, { "kind": "Content", - "text": "{\n " - }, - { - "kind": "Reference", - "text": "classValue" + "text": "method2(): " }, { "kind": "Content", - "text": ": " + "text": "{\n classValue: " }, { "kind": "Reference", @@ -200,15 +136,7 @@ }, { "kind": "Content", - "text": ";\n " - }, - { - "kind": "Reference", - "text": "callback" - }, - { - "kind": "Content", - "text": ": () => number;\n } | undefined" + "text": ";\n callback: () => number;\n } | undefined" }, { "kind": "Content", @@ -217,8 +145,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 2, - "endIndex": 9 + "startIndex": 1, + "endIndex": 4 }, "releaseTag": "Public", "overloadIndex": 1, @@ -235,15 +163,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare const enum " - }, - { - "kind": "Reference", - "text": "ConstEnum" - }, - { - "kind": "Content", - "text": " " + "text": "export declare const enum ConstEnum " } ], "releaseTag": "Public", @@ -254,13 +174,9 @@ "canonicalReference": "api-extractor-scenarios!ConstEnum.One:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "One" - }, { "kind": "Content", - "text": " = " + "text": "One = " }, { "kind": "Content", @@ -270,8 +186,8 @@ "releaseTag": "Public", "name": "One", "initializerTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } }, { @@ -279,13 +195,9 @@ "canonicalReference": "api-extractor-scenarios!ConstEnum.Two:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "Two" - }, { "kind": "Content", - "text": " = " + "text": "Two = " }, { "kind": "Content", @@ -295,8 +207,8 @@ "releaseTag": "Public", "name": "Two", "initializerTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } }, { @@ -304,13 +216,9 @@ "canonicalReference": "api-extractor-scenarios!ConstEnum.Zero:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "Zero" - }, { "kind": "Content", - "text": " = " + "text": "Zero = " }, { "kind": "Content", @@ -320,8 +228,8 @@ "releaseTag": "Public", "name": "Zero", "initializerTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ] @@ -333,15 +241,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export interface " - }, - { - "kind": "Reference", - "text": "IInterface" - }, - { - "kind": "Content", - "text": " " + "text": "export interface IInterface " } ], "releaseTag": "Public", @@ -352,13 +252,9 @@ "canonicalReference": "api-extractor-scenarios!IInterface#member:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "member" - }, { "kind": "Content", - "text": ": " + "text": "member: " }, { "kind": "Content", @@ -372,8 +268,8 @@ "releaseTag": "Public", "name": "member", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ], @@ -386,15 +282,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare namespace " - }, - { - "kind": "Reference", - "text": "NamespaceContainingVariable" - }, - { - "kind": "Content", - "text": " " + "text": "export declare namespace NamespaceContainingVariable " } ], "releaseTag": "Public", @@ -405,13 +293,9 @@ "canonicalReference": "api-extractor-scenarios!NamespaceContainingVariable.constVariable:var", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "constVariable" - }, { "kind": "Content", - "text": ": " + "text": "constVariable: " }, { "kind": "Content", @@ -421,8 +305,8 @@ "releaseTag": "Public", "name": "constVariable", "variableTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } }, { @@ -430,13 +314,9 @@ "canonicalReference": "api-extractor-scenarios!NamespaceContainingVariable.variable:var", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "variable" - }, { "kind": "Content", - "text": ": " + "text": "variable: " }, { "kind": "Content", @@ -446,8 +326,8 @@ "releaseTag": "Public", "name": "variable", "variableTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ] @@ -459,15 +339,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare enum " - }, - { - "kind": "Reference", - "text": "RegularEnum" - }, - { - "kind": "Content", - "text": " " + "text": "export declare enum RegularEnum " } ], "releaseTag": "Public", @@ -478,13 +350,9 @@ "canonicalReference": "api-extractor-scenarios!RegularEnum.One:member", "docComment": "/**\n * These are some docs for One\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "One" - }, { "kind": "Content", - "text": " = " + "text": "One = " }, { "kind": "Content", @@ -494,8 +362,8 @@ "releaseTag": "Public", "name": "One", "initializerTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } }, { @@ -503,13 +371,9 @@ "canonicalReference": "api-extractor-scenarios!RegularEnum.Two:member", "docComment": "/**\n * These are some docs for Two\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "Two" - }, { "kind": "Content", - "text": " = " + "text": "Two = " }, { "kind": "Content", @@ -519,8 +383,8 @@ "releaseTag": "Public", "name": "Two", "initializerTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } }, { @@ -528,13 +392,9 @@ "canonicalReference": "api-extractor-scenarios!RegularEnum.Zero:member", "docComment": "/**\n * These are some docs for Zero\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "Zero" - }, { "kind": "Content", - "text": " = " + "text": "Zero = " }, { "kind": "Content", @@ -544,8 +404,8 @@ "releaseTag": "Public", "name": "Zero", "initializerTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ] @@ -557,15 +417,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "SimpleClass" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class SimpleClass " } ], "releaseTag": "Public", @@ -576,13 +428,9 @@ "canonicalReference": "api-extractor-scenarios!SimpleClass#member:member(1)", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "member" - }, { "kind": "Content", - "text": "(): " + "text": "member(): " }, { "kind": "Content", @@ -595,8 +443,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -611,13 +459,9 @@ "canonicalReference": "api-extractor-scenarios!VARIABLE:var", "docComment": "/**\n * @public\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "VARIABLE" - }, { "kind": "Content", - "text": ": " + "text": "VARIABLE: " }, { "kind": "Content", @@ -627,8 +471,8 @@ "releaseTag": "Public", "name": "VARIABLE", "variableTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ] diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport/api-extractor-scenarios.api.json index d78684206ae..dca6d2b0978 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "IFile" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class IFile " } ], "releaseTag": "Public", @@ -41,13 +33,9 @@ "canonicalReference": "api-extractor-scenarios!IFile#containingFolder:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "containingFolder" - }, { "kind": "Content", - "text": ": " + "text": "containingFolder: " }, { "kind": "Reference", @@ -62,8 +50,8 @@ "releaseTag": "Public", "name": "containingFolder", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "isStatic": false } @@ -77,15 +65,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "IFolder" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class IFolder " } ], "releaseTag": "Public", @@ -96,13 +76,9 @@ "canonicalReference": "api-extractor-scenarios!IFolder#containingFolder:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "containingFolder" - }, { "kind": "Content", - "text": ": " + "text": "containingFolder: " }, { "kind": "Reference", @@ -121,8 +97,8 @@ "releaseTag": "Public", "name": "containingFolder", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 4 + "startIndex": 1, + "endIndex": 3 }, "isStatic": false }, @@ -131,13 +107,9 @@ "canonicalReference": "api-extractor-scenarios!IFolder#files:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "files" - }, { "kind": "Content", - "text": ": " + "text": "files: " }, { "kind": "Reference", @@ -156,8 +128,8 @@ "releaseTag": "Public", "name": "files", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 4 + "startIndex": 1, + "endIndex": 3 }, "isStatic": false } diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport2/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport2/api-extractor-scenarios.api.json index 08c03f40115..0acf135f11c 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport2/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/circularImport2/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "A" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class A " } ], "releaseTag": "Public", @@ -45,15 +37,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "B" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class B " } ], "releaseTag": "Public", @@ -68,15 +52,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "IFile" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class IFile " } ], "releaseTag": "Public", @@ -87,13 +63,9 @@ "canonicalReference": "api-extractor-scenarios!IFile#containingFolder:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "containingFolder" - }, { "kind": "Content", - "text": ": " + "text": "containingFolder: " }, { "kind": "Reference", @@ -108,8 +80,8 @@ "releaseTag": "Public", "name": "containingFolder", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "isStatic": false } @@ -123,15 +95,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "IFolder" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class IFolder " } ], "releaseTag": "Public", @@ -142,13 +106,9 @@ "canonicalReference": "api-extractor-scenarios!IFolder#containingFolder:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "containingFolder" - }, { "kind": "Content", - "text": ": " + "text": "containingFolder: " }, { "kind": "Reference", @@ -167,8 +127,8 @@ "releaseTag": "Public", "name": "containingFolder", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 4 + "startIndex": 1, + "endIndex": 3 }, "isStatic": false }, @@ -177,13 +137,9 @@ "canonicalReference": "api-extractor-scenarios!IFolder#files:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "files" - }, { "kind": "Content", - "text": ": " + "text": "files: " }, { "kind": "Reference", @@ -202,8 +158,8 @@ "releaseTag": "Public", "name": "files", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 4 + "startIndex": 1, + "endIndex": 3 }, "isStatic": false } diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint/api-extractor-scenarios.api.json index ba722a2ba78..7a6e617b407 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export default class " - }, - { - "kind": "Reference", - "text": "DefaultClass" - }, - { - "kind": "Content", - "text": " " + "text": "export default class DefaultClass " } ], "releaseTag": "Public", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint2/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint2/api-extractor-scenarios.api.json index c3ead7e6e28..ee0930c3383 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint2/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint2/api-extractor-scenarios.api.json @@ -20,13 +20,9 @@ "canonicalReference": "api-extractor-scenarios!defaultFunctionStatement:var", "docComment": "/**\n * @public\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "defaultFunctionStatement" - }, { "kind": "Content", - "text": ": " + "text": "defaultFunctionStatement: " }, { "kind": "Content", @@ -36,8 +32,8 @@ "releaseTag": "Public", "name": "defaultFunctionStatement", "variableTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ] diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint3/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint3/api-extractor-scenarios.api.json index 6a0c7a1c392..f77ec75f57e 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint3/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint3/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export default function " - }, - { - "kind": "Reference", - "text": "defaultFunctionDeclaration" - }, - { - "kind": "Content", - "text": "(): " + "text": "export default function defaultFunctionDeclaration(): " }, { "kind": "Content", @@ -42,8 +34,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint4/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint4/api-extractor-scenarios.api.json index 1726fd0e68e..4354fcdc45c 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint4/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/defaultExportOfEntryPoint4/api-extractor-scenarios.api.json @@ -20,13 +20,9 @@ "canonicalReference": "api-extractor-scenarios!_default:var", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "_default" - }, { "kind": "Content", - "text": ": " + "text": "_default: " }, { "kind": "Content", @@ -36,8 +32,8 @@ "releaseTag": "Public", "name": "_default", "variableTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ] diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/docReferences/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/docReferences/api-extractor-scenarios.api.json index e33f3429525..a6462604260 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/docReferences/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/docReferences/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "failWithBrokenLink" - }, - { - "kind": "Content", - "text": "(): " + "text": "export declare function failWithBrokenLink(): " }, { "kind": "Content", @@ -42,8 +34,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -57,15 +49,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "failWithMissingReference" - }, - { - "kind": "Content", - "text": "(): " + "text": "export declare function failWithMissingReference(): " }, { "kind": "Content", @@ -77,8 +61,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -92,15 +76,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare namespace " - }, - { - "kind": "Reference", - "text": "MyNamespace" - }, - { - "kind": "Content", - "text": " " + "text": "export declare namespace MyNamespace " } ], "releaseTag": "Public", @@ -113,15 +89,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "class " - }, - { - "kind": "Reference", - "text": "MyClass" - }, - { - "kind": "Content", - "text": " " + "text": "class MyClass " } ], "releaseTag": "Public", @@ -132,21 +100,9 @@ "canonicalReference": "api-extractor-scenarios!MyNamespace.MyClass#myMethod:member(1)", "docComment": "/**\n * Summary for myMethod\n *\n * @remarks\n *\n * Remarks for myMethod\n *\n * @param x - the parameter\n *\n * @returns a number\n *\n * @beta\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "myMethod" - }, { "kind": "Content", - "text": "(" - }, - { - "kind": "Reference", - "text": "x" - }, - { - "kind": "Content", - "text": ": " + "text": "myMethod(x: " }, { "kind": "Content", @@ -167,8 +123,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 6, - "endIndex": 7 + "startIndex": 3, + "endIndex": 4 }, "releaseTag": "Beta", "overloadIndex": 1, @@ -176,8 +132,8 @@ { "parameterName": "x", "parameterTypeTokenRange": { - "startIndex": 4, - "endIndex": 5 + "startIndex": 1, + "endIndex": 2 } } ], @@ -195,15 +151,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "succeedForNow" - }, - { - "kind": "Content", - "text": "(): " + "text": "export declare function succeedForNow(): " }, { "kind": "Content", @@ -215,8 +163,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -230,15 +178,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "testSimple" - }, - { - "kind": "Content", - "text": "(): " + "text": "export declare function testSimple(): " }, { "kind": "Content", @@ -250,8 +190,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/docReferences2/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/docReferences2/api-extractor-scenarios.api.json index 9bfdc56a54f..86d8e196460 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/docReferences2/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/docReferences2/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "CyclicA" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class CyclicA " } ], "releaseTag": "Public", @@ -41,13 +33,9 @@ "canonicalReference": "api-extractor-scenarios!CyclicA#methodA1:member(1)", "docComment": "/**\n * THE COMMENT\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "methodA1" - }, { "kind": "Content", - "text": "(): " + "text": "methodA1(): " }, { "kind": "Content", @@ -60,8 +48,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -73,13 +61,9 @@ "canonicalReference": "api-extractor-scenarios!CyclicA#methodA3:member(1)", "docComment": "/**\n * THE COMMENT\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "methodA3" - }, { "kind": "Content", - "text": "(): " + "text": "methodA3(): " }, { "kind": "Content", @@ -92,8 +76,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -110,15 +94,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "CyclicB" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class CyclicB " } ], "releaseTag": "Public", @@ -129,13 +105,9 @@ "canonicalReference": "api-extractor-scenarios!CyclicB#methodB2:member(1)", "docComment": "/**\n * THE COMMENT\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "methodB2" - }, { "kind": "Content", - "text": "(): " + "text": "methodB2(): " }, { "kind": "Content", @@ -148,8 +120,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -161,13 +133,9 @@ "canonicalReference": "api-extractor-scenarios!CyclicB#methodB4:member(1)", "docComment": "/**\n * THE COMMENT\n */\n", "excerptTokens": [ - { - "kind": "Reference", - "text": "methodB4" - }, { "kind": "Content", - "text": "(): " + "text": "methodB4(): " }, { "kind": "Content", @@ -180,8 +148,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -198,15 +166,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "FailWithSelfReference" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class FailWithSelfReference " } ], "releaseTag": "Public", @@ -217,13 +177,9 @@ "canonicalReference": "api-extractor-scenarios!FailWithSelfReference#method1:member(1)", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "method1" - }, { "kind": "Content", - "text": "(): " + "text": "method1(): " }, { "kind": "Content", @@ -236,8 +192,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -249,13 +205,9 @@ "canonicalReference": "api-extractor-scenarios!FailWithSelfReference#method2:member(1)", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "method2" - }, { "kind": "Content", - "text": "(): " + "text": "method2(): " }, { "kind": "Content", @@ -268,8 +220,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/docReferences3/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/docReferences3/api-extractor-scenarios.api.json index 1fe99068e90..66ec4456e3e 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/docReferences3/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/docReferences3/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export interface " - }, - { - "kind": "Reference", - "text": "A" - }, - { - "kind": "Content", - "text": " " + "text": "export interface A " } ], "releaseTag": "Public", @@ -41,13 +33,9 @@ "canonicalReference": "api-extractor-scenarios!A#myProperty:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "myProperty" - }, { "kind": "Content", - "text": ": " + "text": "myProperty: " }, { "kind": "Content", @@ -61,8 +49,8 @@ "releaseTag": "Public", "name": "myProperty", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ], @@ -75,15 +63,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare namespace " - }, - { - "kind": "Reference", - "text": "A" - }, - { - "kind": "Content", - "text": " " + "text": "export declare namespace A " } ], "releaseTag": "Public", @@ -96,15 +76,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "class " - }, - { - "kind": "Reference", - "text": "B" - }, - { - "kind": "Content", - "text": " " + "text": "class B " } ], "releaseTag": "Public", @@ -115,13 +87,9 @@ "canonicalReference": "api-extractor-scenarios!A.B#myMethod:member(1)", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "myMethod" - }, { "kind": "Content", - "text": "(): " + "text": "myMethod(): " }, { "kind": "Content", @@ -134,8 +102,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -154,15 +122,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "failWithAmbiguity" - }, - { - "kind": "Content", - "text": "(): " + "text": "export declare function failWithAmbiguity(): " }, { "kind": "Content", @@ -174,8 +134,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -189,15 +149,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "succeedWithExternalReference" - }, - { - "kind": "Content", - "text": "(): " + "text": "export declare function succeedWithExternalReference(): " }, { "kind": "Content", @@ -209,8 +161,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -224,15 +176,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "succeedWithSelector" - }, - { - "kind": "Content", - "text": "(): " + "text": "export declare function succeedWithSelector(): " }, { "kind": "Content", @@ -244,8 +188,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/exportDuplicate/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/exportDuplicate/api-extractor-scenarios.api.json index 17c76287b83..c729a0ebc98 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/exportDuplicate/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/exportDuplicate/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "X" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class X " } ], "releaseTag": "Public", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/exportEquals/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/exportEquals/api-extractor-scenarios.api.json index 824e025a995..b8eee943395 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/exportEquals/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/exportEquals/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export interface " - }, - { - "kind": "Reference", - "text": "ITeamsContext" - }, - { - "kind": "Content", - "text": " " + "text": "export interface ITeamsContext " } ], "releaseTag": "Public", @@ -41,13 +33,9 @@ "canonicalReference": "api-extractor-scenarios!ITeamsContext#context:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "context" - }, { "kind": "Content", - "text": ": " + "text": "context: " }, { "kind": "Reference", @@ -62,8 +50,8 @@ "releaseTag": "Public", "name": "context", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ], diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/exportStar/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/exportStar/api-extractor-scenarios.api.json index 87418952aa6..3b7acb4d56b 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/exportStar/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/exportStar/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "A" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class A " } ], "releaseTag": "Public", @@ -45,15 +37,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "B" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class B " } ], "releaseTag": "Public", @@ -68,15 +52,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "C" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class C " } ], "releaseTag": "Public", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/exportStar2/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/exportStar2/api-extractor-scenarios.api.json index bbc59f0821e..97166819e35 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/exportStar2/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/exportStar2/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "A" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class A " } ], "releaseTag": "Public", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/exportStar3/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/exportStar3/api-extractor-scenarios.api.json index bbc59f0821e..97166819e35 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/exportStar3/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/exportStar3/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "A" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class A " } ], "releaseTag": "Public", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/importEquals/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/importEquals/api-extractor-scenarios.api.json index bf2dc44a839..98d8fecbf06 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/importEquals/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/importEquals/api-extractor-scenarios.api.json @@ -22,23 +22,15 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "useColors" - }, - { - "kind": "Content", - "text": "(): " + "text": "export declare function useColors(): " }, { "kind": "Content", - "text": "typeof " + "text": "typeof colors." }, { "kind": "Reference", - "text": "colors.zebra", + "text": "zebra", "canonicalReference": "colors!zebra:var" }, { @@ -47,8 +39,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 5 + "startIndex": 1, + "endIndex": 3 }, "releaseTag": "Public", "overloadIndex": 1, diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/inconsistentReleaseTags/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/inconsistentReleaseTags/api-extractor-scenarios.api.json index b3a58aeb6ac..25962c1f0f7 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/inconsistentReleaseTags/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/inconsistentReleaseTags/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export interface " - }, - { - "kind": "Reference", - "text": "IBeta" - }, - { - "kind": "Content", - "text": " " + "text": "export interface IBeta " } ], "releaseTag": "Beta", @@ -41,13 +33,9 @@ "canonicalReference": "api-extractor-scenarios!IBeta#x:member", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "x" - }, { "kind": "Content", - "text": ": " + "text": "x: " }, { "kind": "Content", @@ -61,8 +49,8 @@ "releaseTag": "Beta", "name": "x", "propertyTypeTokenRange": { - "startIndex": 2, - "endIndex": 3 + "startIndex": 1, + "endIndex": 2 } } ], @@ -75,15 +63,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "publicFunctionReturnsBeta" - }, - { - "kind": "Content", - "text": "(): " + "text": "export declare function publicFunctionReturnsBeta(): " }, { "kind": "Reference", @@ -96,8 +76,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf/api-extractor-scenarios.api.json index ffc12d3899d..c15727f370c 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "f" - }, - { - "kind": "Content", - "text": "(): " + "text": "export declare function f(): " }, { "kind": "Content", @@ -51,8 +43,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 6 + "startIndex": 1, + "endIndex": 4 }, "releaseTag": "Public", "overloadIndex": 1, @@ -66,15 +58,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "g" - }, - { - "kind": "Content", - "text": "(): " + "text": "export declare function g(): " }, { "kind": "Content", @@ -95,8 +79,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 6 + "startIndex": 1, + "endIndex": 4 }, "releaseTag": "Public", "overloadIndex": 1, diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/api-extractor-scenarios.api.json index 643190bc47f..2f55e1cf757 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf2/api-extractor-scenarios.api.json @@ -22,27 +22,11 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "f" + "text": "export declare function f(): " }, { "kind": "Content", - "text": "(): " - }, - { - "kind": "Content", - "text": "{\n " - }, - { - "kind": "Reference", - "text": "a" - }, - { - "kind": "Content", - "text": ": number;\n}" + "text": "{\n a: number;\n}" }, { "kind": "Content", @@ -50,8 +34,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 6 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -65,23 +49,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare function " - }, - { - "kind": "Reference", - "text": "g" - }, - { - "kind": "Content", - "text": "(" - }, - { - "kind": "Reference", - "text": "callback" - }, - { - "kind": "Content", - "text": ": " + "text": "export declare function g(callback: " }, { "kind": "Content", @@ -111,8 +79,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 8, - "endIndex": 10 + "startIndex": 4, + "endIndex": 6 }, "releaseTag": "Public", "overloadIndex": 1, @@ -120,8 +88,8 @@ { "parameterName": "callback", "parameterTypeTokenRange": { - "startIndex": 5, - "endIndex": 7 + "startIndex": 1, + "endIndex": 3 } } ], diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/typeParameters/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/typeParameters/api-extractor-scenarios.api.json index 189423755b5..fa30f8925dd 100644 --- a/build-tests/api-extractor-scenarios/etc/test-outputs/typeParameters/api-extractor-scenarios.api.json +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/typeParameters/api-extractor-scenarios.api.json @@ -22,15 +22,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "ClassWithGenericMethod" - }, - { - "kind": "Content", - "text": " " + "text": "export declare class ClassWithGenericMethod " } ], "releaseTag": "Public", @@ -41,21 +33,9 @@ "canonicalReference": "api-extractor-scenarios!ClassWithGenericMethod#method:member(1)", "docComment": "", "excerptTokens": [ - { - "kind": "Reference", - "text": "method" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "T" - }, { "kind": "Content", - "text": ">(): " + "text": "method(): " }, { "kind": "Content", @@ -68,8 +48,8 @@ ], "isStatic": false, "returnTypeTokenRange": { - "startIndex": 4, - "endIndex": 5 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -99,23 +79,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "GenericClass" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "T" - }, - { - "kind": "Content", - "text": "> " + "text": "export declare class GenericClass " } ], "releaseTag": "Public", @@ -143,23 +107,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare class " - }, - { - "kind": "Reference", - "text": "GenericClassWithConstraint" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "T" - }, - { - "kind": "Content", - "text": " extends " + "text": "export declare class GenericClassWithConstraint(): " + "text": "export declare function genericFunction(): " }, { "kind": "Content", @@ -275,8 +191,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 5, - "endIndex": 6 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -303,23 +219,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export interface " - }, - { - "kind": "Reference", - "text": "GenericInterface" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "T" - }, - { - "kind": "Content", - "text": "> " + "text": "export interface GenericInterface " } ], "releaseTag": "Public", @@ -347,26 +247,10 @@ "excerptTokens": [ { "kind": "Content", - "text": "export declare type " - }, - { - "kind": "Reference", - "text": "GenericTypeAlias" - }, - { - "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "T" + "text": "export declare type GenericTypeAlias = " }, { "kind": "Content", - "text": "> = " - }, - { - "kind": "Reference", "text": "T" }, { @@ -390,8 +274,8 @@ } ], "typeTokenRange": { - "startIndex": 5, - "endIndex": 6 + "startIndex": 1, + "endIndex": 2 } }, { @@ -401,15 +285,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export interface " - }, - { - "kind": "Reference", - "text": "InterfaceWithGenericCallSignature" - }, - { - "kind": "Content", - "text": " " + "text": "export interface InterfaceWithGenericCallSignature " } ], "releaseTag": "Public", @@ -422,15 +298,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "<" - }, - { - "kind": "Reference", - "text": "T" - }, - { - "kind": "Content", - "text": ">(): " + "text": "(): " }, { "kind": "Content", @@ -442,8 +310,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, @@ -472,15 +340,7 @@ "excerptTokens": [ { "kind": "Content", - "text": "export interface " - }, - { - "kind": "Reference", - "text": "InterfaceWithGenericConstructSignature" - }, - { - "kind": "Content", - "text": " " + "text": "export interface InterfaceWithGenericConstructSignature " } ], "releaseTag": "Public", @@ -493,18 +353,10 @@ "excerptTokens": [ { "kind": "Content", - "text": "new <" - }, - { - "kind": "Reference", - "text": "T" + "text": "new (): " }, { "kind": "Content", - "text": ">(): " - }, - { - "kind": "Reference", "text": "T" }, { @@ -513,8 +365,8 @@ } ], "returnTypeTokenRange": { - "startIndex": 3, - "endIndex": 4 + "startIndex": 1, + "endIndex": 2 }, "releaseTag": "Public", "overloadIndex": 1, From d395618ab0bcf08dccc141c09e1e24b1d5db1d77 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 10 Sep 2019 11:03:37 -0700 Subject: [PATCH 8/8] Fix issue with duplicate yaml references --- .../src/documenters/YamlDocumenter.ts | 32 ++++++++----------- .../etc/api-documenter-test.api.json | 28 ++++++++++++++++ .../etc/api-documenter-test.api.md | 3 ++ .../etc/markdown/api-documenter-test.md | 1 + ...menter-test.yamlreferenceuniquenesstest.md | 16 ++++++++++ .../etc/yaml/api-documenter-test.yml | 13 ++++++++ build-tests/api-documenter-test/src/index.ts | 6 ++++ 7 files changed, 81 insertions(+), 18 deletions(-) create mode 100644 build-tests/api-documenter-test/etc/markdown/api-documenter-test.yamlreferenceuniquenesstest.md diff --git a/apps/api-documenter/src/documenters/YamlDocumenter.ts b/apps/api-documenter/src/documenters/YamlDocumenter.ts index 0826198fa1b..be33d59dd6a 100644 --- a/apps/api-documenter/src/documenters/YamlDocumenter.ts +++ b/apps/api-documenter/src/documenters/YamlDocumenter.ts @@ -116,6 +116,12 @@ export class YamlDocumenter { } private _visitApiItems(apiItem: ApiDocumentedItem, parentYamlFile: IYamlApiFile | undefined): boolean { + let savedYamlReferences: IYamlReferences | undefined; + if (!this._shouldEmbed(apiItem.kind)) { + savedYamlReferences = this._yamlReferences; + this._yamlReferences = undefined; + } + const yamlItem: IYamlItem | undefined = this._generateYamlItem(apiItem); if (!yamlItem) { return false; @@ -155,17 +161,12 @@ export class YamlDocumenter { } } - if (this._yamlReferences) { - if (this._yamlReferences.references.length > 0) { - if (newYamlFile.references) { - newYamlFile.references = [...newYamlFile.references, ...this._yamlReferences.references]; - } else { - newYamlFile.references = this._yamlReferences.references; - } - } - this._yamlReferences = undefined; + if (this._yamlReferences && this._yamlReferences.references.length > 0) { + newYamlFile.references = this._yamlReferences.references; } + this._yamlReferences = savedYamlReferences; + const yamlFilePath: string = this._getYamlFilePath(apiItem); if (apiItem.kind === ApiItemKind.Package) { @@ -175,15 +176,10 @@ export class YamlDocumenter { this._writeYamlFile(newYamlFile, yamlFilePath, 'UniversalReference', yamlApiSchema); if (parentYamlFile) { - if (!parentYamlFile.references) { - parentYamlFile.references = []; - } - - parentYamlFile.references.push({ - uid: this._getUid(apiItem), - name: this._getYamlItemName(apiItem) - }); - + this._recordYamlReference( + this._ensureYamlReferences(), + this._getUid(apiItem), + this._getYamlItemName(apiItem)); } } diff --git a/build-tests/api-documenter-test/etc/api-documenter-test.api.json b/build-tests/api-documenter-test/etc/api-documenter-test.api.json index f90d0628ef4..a6ccde1dff2 100644 --- a/build-tests/api-documenter-test/etc/api-documenter-test.api.json +++ b/build-tests/api-documenter-test/etc/api-documenter-test.api.json @@ -1602,6 +1602,34 @@ } ], "implementsTokenRanges": [] + }, + { + "kind": "Function", + "canonicalReference": "api-documenter-test!yamlReferenceUniquenessTest:function(1)", + "docComment": "/**\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export declare function yamlReferenceUniquenessTest(): " + }, + { + "kind": "Reference", + "text": "IDocInterface1", + "canonicalReference": "api-documenter-test!IDocInterface1:interface" + }, + { + "kind": "Content", + "text": ";" + } + ], + "returnTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "overloadIndex": 1, + "parameters": [], + "name": "yamlReferenceUniquenessTest" } ] } diff --git a/build-tests/api-documenter-test/etc/api-documenter-test.api.md b/build-tests/api-documenter-test/etc/api-documenter-test.api.md index 46d3270988a..c529a151a7d 100644 --- a/build-tests/api-documenter-test/etc/api-documenter-test.api.md +++ b/build-tests/api-documenter-test/etc/api-documenter-test.api.md @@ -123,5 +123,8 @@ export class SystemEvent { addHandler(handler: () => void): void; } +// @public (undocumented) +export function yamlReferenceUniquenessTest(): IDocInterface1; + ``` diff --git a/build-tests/api-documenter-test/etc/markdown/api-documenter-test.md b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.md index 3dd608da7a6..1bf11d1b13f 100644 --- a/build-tests/api-documenter-test/etc/markdown/api-documenter-test.md +++ b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.md @@ -28,6 +28,7 @@ This project tests various documentation generation scenarios and doc comment sy | Function | Description | | --- | --- | | [globalFunction(x)](./api-documenter-test.globalfunction.md) | An exported function | +| [yamlReferenceUniquenessTest()](./api-documenter-test.yamlreferenceuniquenesstest.md) | | ## Interfaces diff --git a/build-tests/api-documenter-test/etc/markdown/api-documenter-test.yamlreferenceuniquenesstest.md b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.yamlreferenceuniquenesstest.md new file mode 100644 index 00000000000..36a15dd3652 --- /dev/null +++ b/build-tests/api-documenter-test/etc/markdown/api-documenter-test.yamlreferenceuniquenesstest.md @@ -0,0 +1,16 @@ + + +[Home](./index.md) > [api-documenter-test](./api-documenter-test.md) > [yamlReferenceUniquenessTest](./api-documenter-test.yamlreferenceuniquenesstest.md) + +## yamlReferenceUniquenessTest() function + + +Signature: + +```typescript +export declare function yamlReferenceUniquenessTest(): IDocInterface1; +``` +Returns: + +`IDocInterface1` + diff --git a/build-tests/api-documenter-test/etc/yaml/api-documenter-test.yml b/build-tests/api-documenter-test/etc/yaml/api-documenter-test.yml index 740dd7df021..aa9f937378a 100644 --- a/build-tests/api-documenter-test/etc/yaml/api-documenter-test.yml +++ b/build-tests/api-documenter-test/etc/yaml/api-documenter-test.yml @@ -24,6 +24,7 @@ items: - 'api-documenter-test!IDocInterface6:interface' - 'api-documenter-test!OuterNamespace.InnerNamespace.nestedFunction:function(1)' - 'api-documenter-test!SystemEvent:class' + - 'api-documenter-test!yamlReferenceUniquenessTest:function(1)' - uid: 'api-documenter-test!globalFunction:function(1)' summary: An exported function name: globalFunction(x) @@ -60,6 +61,18 @@ items: description: '' type: - number + - uid: 'api-documenter-test!yamlReferenceUniquenessTest:function(1)' + name: yamlReferenceUniquenessTest() + fullName: yamlReferenceUniquenessTest() + langs: + - typeScript + type: function + syntax: + content: 'export declare function yamlReferenceUniquenessTest(): IDocInterface1;' + return: + type: + - 'api-documenter-test!IDocInterface1:interface' + description: '' references: - uid: 'api-documenter-test!DocBaseClass:class' name: DocBaseClass diff --git a/build-tests/api-documenter-test/src/index.ts b/build-tests/api-documenter-test/src/index.ts index 78b2be798e8..090978947fa 100644 --- a/build-tests/api-documenter-test/src/index.ts +++ b/build-tests/api-documenter-test/src/index.ts @@ -12,6 +12,7 @@ export * from './DocClass1'; export * from './DocEnums'; +import { IDocInterface1 } from './DocClass1'; /** * A type alias @@ -55,3 +56,8 @@ export namespace OuterNamespace { */ export let nestedVariable: boolean = false; } + +/** + * @public + */ +export declare function yamlReferenceUniquenessTest(): IDocInterface1; \ No newline at end of file