@@ -10,6 +10,25 @@ import { WorkingPackage } from '../collector/WorkingPackage';
1010import { AstModule } from './AstModule' ;
1111import { AstImport } from './AstImport' ;
1212
13+ /**
14+ * Used by `AstReferenceResolver` to report a failed resolution.
15+ *
16+ * @privateRemarks
17+ * This class is similar to an `Error` object, but the intent of `ResolverFailure` is to describe
18+ * why a reference could not be resolved. This information could be used to throw an actual `Error` object,
19+ * but normally it is handed off to the `MessageRouter` instead.
20+ */
21+ export class ResolverFailure {
22+ /**
23+ * Details about why the failure occurred.
24+ */
25+ public readonly reason : string ;
26+
27+ public constructor ( reason : string ) {
28+ this . reason = reason ;
29+ }
30+ }
31+
1332/**
1433 * This resolves a TSDoc declaration reference by walking the `AstSymbolTable` compiler state.
1534 *
@@ -27,67 +46,67 @@ export class AstReferenceResolver {
2746 this . _workingPackage = workingPackage ;
2847 }
2948
30- public resolve ( declarationReference : tsdoc . DocDeclarationReference ) : AstDeclaration | Error {
49+ public resolve ( declarationReference : tsdoc . DocDeclarationReference ) : AstDeclaration | ResolverFailure {
3150 // Is it referring to the working package?
3251 if ( declarationReference . packageName !== undefined
3352 && declarationReference . packageName !== this . _workingPackage . name ) {
34- return new Error ( 'External package references are not supported' ) ;
53+ return new ResolverFailure ( 'External package references are not supported' ) ;
3554 }
3655
3756 // Is it a path-based import?
3857 if ( declarationReference . importPath ) {
39- return new Error ( 'Import paths are not supported' ) ;
58+ return new ResolverFailure ( 'Import paths are not supported' ) ;
4059 }
4160
4261 const astModule : AstModule = this . _astSymbolTable . fetchAstModuleFromWorkingPackage (
4362 this . _workingPackage . entryPointSourceFile ) ;
4463
4564 if ( declarationReference . memberReferences . length === 0 ) {
46- return new Error ( 'Package references are not supported' ) ;
65+ return new ResolverFailure ( 'Package references are not supported' ) ;
4766 }
4867
4968 const rootMemberReference : tsdoc . DocMemberReference = declarationReference . memberReferences [ 0 ] ;
5069
51- const exportName : string | Error = this . _getMemberReferenceIdentifier ( rootMemberReference ) ;
52- if ( exportName instanceof Error ) {
70+ const exportName : string | ResolverFailure = this . _getMemberReferenceIdentifier ( rootMemberReference ) ;
71+ if ( exportName instanceof ResolverFailure ) {
5372 return exportName ;
5473 }
5574
5675 const rootAstEntity : AstEntity | undefined = this . _astSymbolTable . tryGetExportOfAstModule (
5776 exportName , astModule ) ;
5877
5978 if ( rootAstEntity === undefined ) {
60- return new Error ( `The package "${ this . _workingPackage . name } " does not have an export "${ exportName } "` ) ;
79+ return new ResolverFailure ( `The package "${ this . _workingPackage . name } " does not have an export "${ exportName } "` ) ;
6180 }
6281
6382 if ( rootAstEntity instanceof AstImport ) {
64- return new Error ( 'Reexported declarations are not supported' ) ;
83+ return new ResolverFailure ( 'Reexported declarations are not supported' ) ;
6584 }
6685
67- let currentDeclaration : AstDeclaration | Error = this . _selectDeclaration ( rootAstEntity . astDeclarations ,
86+ let currentDeclaration : AstDeclaration | ResolverFailure = this . _selectDeclaration ( rootAstEntity . astDeclarations ,
6887 rootMemberReference , rootAstEntity . localName ) ;
6988
70- if ( currentDeclaration instanceof Error ) {
89+ if ( currentDeclaration instanceof ResolverFailure ) {
7190 return currentDeclaration ;
7291 }
7392
7493 for ( let index : number = 1 ; index < declarationReference . memberReferences . length ; ++ index ) {
7594 const memberReference : tsdoc . DocMemberReference = declarationReference . memberReferences [ index ] ;
7695
77- const memberName : string | Error = this . _getMemberReferenceIdentifier ( memberReference ) ;
78- if ( memberName instanceof Error ) {
96+ const memberName : string | ResolverFailure = this . _getMemberReferenceIdentifier ( memberReference ) ;
97+ if ( memberName instanceof ResolverFailure ) {
7998 return memberName ;
8099 }
81100
82101 const matchingChildren : ReadonlyArray < AstDeclaration > = currentDeclaration . findChildrenWithName ( memberName ) ;
83102 if ( matchingChildren . length === 0 ) {
84- return new Error ( `No member was found with name "${ memberName } "` ) ;
103+ return new ResolverFailure ( `No member was found with name "${ memberName } "` ) ;
85104 }
86105
87- const selectedDeclaration : AstDeclaration | Error = this . _selectDeclaration ( matchingChildren ,
106+ const selectedDeclaration : AstDeclaration | ResolverFailure = this . _selectDeclaration ( matchingChildren ,
88107 memberReference , memberName ) ;
89108
90- if ( selectedDeclaration instanceof Error ) {
109+ if ( selectedDeclaration instanceof ResolverFailure ) {
91110 return selectedDeclaration ;
92111 }
93112
@@ -97,32 +116,32 @@ export class AstReferenceResolver {
97116 return currentDeclaration ;
98117 }
99118
100- private _getMemberReferenceIdentifier ( memberReference : tsdoc . DocMemberReference ) : string | Error {
119+ private _getMemberReferenceIdentifier ( memberReference : tsdoc . DocMemberReference ) : string | ResolverFailure {
101120 if ( memberReference . memberSymbol !== undefined ) {
102- return new Error ( 'ECMAScript symbol selectors are not supported' ) ;
121+ return new ResolverFailure ( 'ECMAScript symbol selectors are not supported' ) ;
103122 }
104123 if ( memberReference . memberIdentifier === undefined ) {
105- return new Error ( 'The member identifier is missing in the root member reference' ) ;
124+ return new ResolverFailure ( 'The member identifier is missing in the root member reference' ) ;
106125 }
107126 return memberReference . memberIdentifier . identifier ;
108127 }
109128
110129 private _selectDeclaration ( astDeclarations : ReadonlyArray < AstDeclaration > ,
111- memberReference : tsdoc . DocMemberReference , astSymbolName : string ) : AstDeclaration | Error {
130+ memberReference : tsdoc . DocMemberReference , astSymbolName : string ) : AstDeclaration | ResolverFailure {
112131
113132 if ( memberReference . selector === undefined ) {
114133 if ( astDeclarations . length === 1 ) {
115134 return astDeclarations [ 0 ] ;
116135 } else {
117- return new Error ( `The reference is ambiguous because "${ astSymbolName } "`
136+ return new ResolverFailure ( `The reference is ambiguous because "${ astSymbolName } "`
118137 + ` has more than one declaration; you need to add a TSDoc member reference selector` ) ;
119138 }
120139 }
121140
122141 const selectorName : string = memberReference . selector . selector ;
123142
124143 if ( memberReference . selector . selectorKind !== tsdoc . SelectorKind . System ) {
125- return new Error ( `The selector "${ selectorName } " is not a supported selector type` ) ;
144+ return new ResolverFailure ( `The selector "${ selectorName } " is not a supported selector type` ) ;
126145 }
127146
128147 let selectorSyntaxKind : ts . SyntaxKind ;
@@ -150,16 +169,16 @@ export class AstReferenceResolver {
150169 selectorSyntaxKind = ts . SyntaxKind . VariableDeclaration ;
151170 break ;
152171 default :
153- return new Error ( `Unsupported system selector "${ selectorName } "` ) ;
172+ return new ResolverFailure ( `Unsupported system selector "${ selectorName } "` ) ;
154173 }
155174
156175 const matches : AstDeclaration [ ] = astDeclarations . filter ( x => x . declaration . kind === selectorSyntaxKind ) ;
157176 if ( matches . length === 0 ) {
158- return new Error ( `A declaration for "${ astSymbolName } " was not found that matches the`
177+ return new ResolverFailure ( `A declaration for "${ astSymbolName } " was not found that matches the`
159178 + ` TSDoc selector "${ selectorName } "` ) ;
160179 }
161180 if ( matches . length > 1 ) {
162- return new Error ( `More than one declaration "${ astSymbolName } " matches the`
181+ return new ResolverFailure ( `More than one declaration "${ astSymbolName } " matches the`
163182 + ` TSDoc selector "${ selectorName } "` ) ;
164183 }
165184 return matches [ 0 ] ;
0 commit comments