3
3
4
4
import { DeclarationReference } from '@microsoft/tsdoc/lib-commonjs/beta/DeclarationReference' ;
5
5
import { ApiDocumentedItem , IApiDocumentedItemJson , IApiDocumentedItemOptions } from './ApiDocumentedItem' ;
6
+ import { ApiItem } from './ApiItem' ;
6
7
import { Excerpt , ExcerptToken , IExcerptTokenRange , IExcerptToken } from '../mixins/Excerpt' ;
7
8
import { DeserializerContext } from '../model/DeserializerContext' ;
8
9
import { SourceLocation } from '../model/SourceLocation' ;
@@ -38,7 +39,8 @@ export interface IApiDeclaredItemJson extends IApiDocumentedItemJson {
38
39
export class ApiDeclaredItem extends ApiDocumentedItem {
39
40
private _excerptTokens : ExcerptToken [ ] ;
40
41
private _excerpt : Excerpt ;
41
- private _sourceLocation : SourceLocation ;
42
+ private _fileUrlPath ?: string ;
43
+ private _sourceLocation ?: SourceLocation ;
42
44
43
45
public constructor ( options : IApiDeclaredItemOptions ) {
44
46
super ( options ) ;
@@ -51,14 +53,7 @@ export class ApiDeclaredItem extends ApiDocumentedItem {
51
53
return new ExcerptToken ( token . kind , token . text , canonicalReference ) ;
52
54
} ) ;
53
55
this . _excerpt = new Excerpt ( this . excerptTokens , { startIndex : 0 , endIndex : this . excerptTokens . length } ) ;
54
-
55
- const projectFolderUrl : string | undefined = this . getAssociatedPackage ( ) ?. projectFolderUrl ;
56
- const fileUrlPath : string | undefined = options . fileUrlPath || this . _parentSourceLocation ?. fileUrlPath ;
57
-
58
- this . _sourceLocation = new SourceLocation ( {
59
- projectFolderUrl : projectFolderUrl ,
60
- fileUrlPath : fileUrlPath
61
- } ) ;
56
+ this . _fileUrlPath = options . fileUrlPath ;
62
57
}
63
58
64
59
/** @override */
@@ -88,9 +83,21 @@ export class ApiDeclaredItem extends ApiDocumentedItem {
88
83
}
89
84
90
85
/**
91
- * The source location where the API item is declared.
86
+ * The file URL path relative to the `projectFolder` and `projectFolderURL` fields
87
+ * as defined in the `api-extractor.json` config. Is `undefined` if the path is
88
+ * the same as the parent API item's.
89
+ */
90
+ public get fileUrlPath ( ) : string | undefined {
91
+ return this . _fileUrlPath ;
92
+ }
93
+
94
+ /**
95
+ * Returns the source location where the API item is declared.
92
96
*/
93
97
public get sourceLocation ( ) : SourceLocation {
98
+ if ( ! this . _sourceLocation ) {
99
+ this . _sourceLocation = this . _buildSourceLocation ( ) ;
100
+ }
94
101
return this . _sourceLocation ;
95
102
}
96
103
@@ -137,11 +144,10 @@ export class ApiDeclaredItem extends ApiDocumentedItem {
137
144
138
145
// Only serialize this API item's file URL path if it exists and it's different from its parent's
139
146
// (a little optimization to keep the doc model succinct).
140
- if (
141
- this . _sourceLocation . fileUrlPath &&
142
- this . _sourceLocation . fileUrlPath !== this . _parentSourceLocation ?. fileUrlPath
143
- ) {
144
- jsonObject . fileUrlPath = this . _sourceLocation . fileUrlPath ;
147
+ if ( this . fileUrlPath ) {
148
+ if ( ! ( this . parent instanceof ApiDeclaredItem ) || this . fileUrlPath !== this . parent . fileUrlPath ) {
149
+ jsonObject . fileUrlPath = this . fileUrlPath ;
150
+ }
145
151
}
146
152
}
147
153
@@ -152,7 +158,23 @@ export class ApiDeclaredItem extends ApiDocumentedItem {
152
158
return new Excerpt ( this . excerptTokens , tokenRange ) ;
153
159
}
154
160
155
- private get _parentSourceLocation ( ) : SourceLocation | undefined {
156
- return this . parent instanceof ApiDeclaredItem ? this . parent . sourceLocation : undefined ;
161
+ /**
162
+ * Builds the cached object used by the `sourceLocation` property.
163
+ */
164
+ private _buildSourceLocation ( ) : SourceLocation {
165
+ const projectFolderUrl : string | undefined = this . getAssociatedPackage ( ) ?. projectFolderUrl ;
166
+
167
+ let fileUrlPath : string | undefined ;
168
+ for ( let current : ApiItem | undefined = this ; current !== undefined ; current = current . parent ) {
169
+ if ( current instanceof ApiDeclaredItem && current . fileUrlPath ) {
170
+ fileUrlPath = current . fileUrlPath ;
171
+ break ;
172
+ }
173
+ }
174
+
175
+ return new SourceLocation ( {
176
+ projectFolderUrl : projectFolderUrl ,
177
+ fileUrlPath : fileUrlPath
178
+ } ) ;
157
179
}
158
180
}
0 commit comments