1 | "use strict";
|
2 |
|
3 |
|
4 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
5 | if (k2 === undefined) k2 = k;
|
6 | var desc = Object.getOwnPropertyDescriptor(m, k);
|
7 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
8 | desc = { enumerable: true, get: function() { return m[k]; } };
|
9 | }
|
10 | Object.defineProperty(o, k2, desc);
|
11 | }) : (function(o, m, k, k2) {
|
12 | if (k2 === undefined) k2 = k;
|
13 | o[k2] = m[k];
|
14 | }));
|
15 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
16 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
17 | }) : function(o, v) {
|
18 | o["default"] = v;
|
19 | });
|
20 | var __importStar = (this && this.__importStar) || function (mod) {
|
21 | if (mod && mod.__esModule) return mod;
|
22 | var result = {};
|
23 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
24 | __setModuleDefault(result, mod);
|
25 | return result;
|
26 | };
|
27 | Object.defineProperty(exports, "__esModule", { value: true });
|
28 | exports.AstReferenceResolver = exports.ResolverFailure = void 0;
|
29 | const ts = __importStar(require("typescript"));
|
30 | const tsdoc = __importStar(require("@microsoft/tsdoc"));
|
31 | const AstSymbol_1 = require("./AstSymbol");
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 | class ResolverFailure {
|
41 | constructor(reason) {
|
42 | this.reason = reason;
|
43 | }
|
44 | }
|
45 | exports.ResolverFailure = ResolverFailure;
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 | class AstReferenceResolver {
|
55 | constructor(collector) {
|
56 | this._collector = collector;
|
57 | this._astSymbolTable = collector.astSymbolTable;
|
58 | this._workingPackage = collector.workingPackage;
|
59 | }
|
60 | resolve(declarationReference) {
|
61 |
|
62 | if (declarationReference.packageName !== undefined &&
|
63 | declarationReference.packageName !== this._workingPackage.name) {
|
64 | return new ResolverFailure('External package references are not supported');
|
65 | }
|
66 |
|
67 | if (declarationReference.importPath) {
|
68 | return new ResolverFailure('Import paths are not supported');
|
69 | }
|
70 | const astModule = this._astSymbolTable.fetchAstModuleFromWorkingPackage(this._workingPackage.entryPointSourceFile);
|
71 | if (declarationReference.memberReferences.length === 0) {
|
72 | return new ResolverFailure('Package references are not supported');
|
73 | }
|
74 | const rootMemberReference = declarationReference.memberReferences[0];
|
75 | const exportName = this._getMemberReferenceIdentifier(rootMemberReference);
|
76 | if (exportName instanceof ResolverFailure) {
|
77 | return exportName;
|
78 | }
|
79 | const rootAstEntity = this._astSymbolTable.tryGetExportOfAstModule(exportName, astModule);
|
80 | if (rootAstEntity === undefined) {
|
81 | return new ResolverFailure(`The package "${this._workingPackage.name}" does not have an export "${exportName}"`);
|
82 | }
|
83 | if (!(rootAstEntity instanceof AstSymbol_1.AstSymbol)) {
|
84 | return new ResolverFailure('This type of declaration is not supported yet by the resolver');
|
85 | }
|
86 | let currentDeclaration = this._selectDeclaration(rootAstEntity.astDeclarations, rootMemberReference, rootAstEntity.localName);
|
87 | if (currentDeclaration instanceof ResolverFailure) {
|
88 | return currentDeclaration;
|
89 | }
|
90 | for (let index = 1; index < declarationReference.memberReferences.length; ++index) {
|
91 | const memberReference = declarationReference.memberReferences[index];
|
92 | const memberName = this._getMemberReferenceIdentifier(memberReference);
|
93 | if (memberName instanceof ResolverFailure) {
|
94 | return memberName;
|
95 | }
|
96 | const matchingChildren = currentDeclaration.findChildrenWithName(memberName);
|
97 | if (matchingChildren.length === 0) {
|
98 | return new ResolverFailure(`No member was found with name "${memberName}"`);
|
99 | }
|
100 | const selectedDeclaration = this._selectDeclaration(matchingChildren, memberReference, memberName);
|
101 | if (selectedDeclaration instanceof ResolverFailure) {
|
102 | return selectedDeclaration;
|
103 | }
|
104 | currentDeclaration = selectedDeclaration;
|
105 | }
|
106 | return currentDeclaration;
|
107 | }
|
108 | _getMemberReferenceIdentifier(memberReference) {
|
109 | if (memberReference.memberSymbol !== undefined) {
|
110 | return new ResolverFailure('ECMAScript symbol selectors are not supported');
|
111 | }
|
112 | if (memberReference.memberIdentifier === undefined) {
|
113 | return new ResolverFailure('The member identifier is missing in the root member reference');
|
114 | }
|
115 | return memberReference.memberIdentifier.identifier;
|
116 | }
|
117 | _selectDeclaration(astDeclarations, memberReference, astSymbolName) {
|
118 | const memberSelector = memberReference.selector;
|
119 | if (memberSelector === undefined) {
|
120 | if (astDeclarations.length === 1) {
|
121 | return astDeclarations[0];
|
122 | }
|
123 | else {
|
124 |
|
125 |
|
126 | const nonAncillaryMatch = this._tryDisambiguateAncillaryMatches(astDeclarations);
|
127 | if (nonAncillaryMatch) {
|
128 | return nonAncillaryMatch;
|
129 | }
|
130 | return new ResolverFailure(`The reference is ambiguous because "${astSymbolName}"` +
|
131 | ` has more than one declaration; you need to add a TSDoc member reference selector`);
|
132 | }
|
133 | }
|
134 | switch (memberSelector.selectorKind) {
|
135 | case tsdoc.SelectorKind.System:
|
136 | return this._selectUsingSystemSelector(astDeclarations, memberSelector, astSymbolName);
|
137 | case tsdoc.SelectorKind.Index:
|
138 | return this._selectUsingIndexSelector(astDeclarations, memberSelector, astSymbolName);
|
139 | }
|
140 | return new ResolverFailure(`The selector "${memberSelector.selector}" is not a supported selector type`);
|
141 | }
|
142 | _selectUsingSystemSelector(astDeclarations, memberSelector, astSymbolName) {
|
143 | const selectorName = memberSelector.selector;
|
144 | let selectorSyntaxKind;
|
145 | switch (selectorName) {
|
146 | case 'class':
|
147 | selectorSyntaxKind = ts.SyntaxKind.ClassDeclaration;
|
148 | break;
|
149 | case 'enum':
|
150 | selectorSyntaxKind = ts.SyntaxKind.EnumDeclaration;
|
151 | break;
|
152 | case 'function':
|
153 | selectorSyntaxKind = ts.SyntaxKind.FunctionDeclaration;
|
154 | break;
|
155 | case 'interface':
|
156 | selectorSyntaxKind = ts.SyntaxKind.InterfaceDeclaration;
|
157 | break;
|
158 | case 'namespace':
|
159 | selectorSyntaxKind = ts.SyntaxKind.ModuleDeclaration;
|
160 | break;
|
161 | case 'type':
|
162 | selectorSyntaxKind = ts.SyntaxKind.TypeAliasDeclaration;
|
163 | break;
|
164 | case 'variable':
|
165 | selectorSyntaxKind = ts.SyntaxKind.VariableDeclaration;
|
166 | break;
|
167 | default:
|
168 | return new ResolverFailure(`Unsupported system selector "${selectorName}"`);
|
169 | }
|
170 | const matches = astDeclarations.filter((x) => x.declaration.kind === selectorSyntaxKind);
|
171 | if (matches.length === 0) {
|
172 | return new ResolverFailure(`A declaration for "${astSymbolName}" was not found that matches the` +
|
173 | ` TSDoc selector "${selectorName}"`);
|
174 | }
|
175 | if (matches.length > 1) {
|
176 |
|
177 |
|
178 | const nonAncillaryMatch = this._tryDisambiguateAncillaryMatches(matches);
|
179 | if (nonAncillaryMatch) {
|
180 | return nonAncillaryMatch;
|
181 | }
|
182 | return new ResolverFailure(`More than one declaration "${astSymbolName}" matches the TSDoc selector "${selectorName}"`);
|
183 | }
|
184 | return matches[0];
|
185 | }
|
186 | _selectUsingIndexSelector(astDeclarations, memberSelector, astSymbolName) {
|
187 | const selectorOverloadIndex = parseInt(memberSelector.selector);
|
188 | const matches = [];
|
189 | for (const astDeclaration of astDeclarations) {
|
190 | const overloadIndex = this._collector.getOverloadIndex(astDeclaration);
|
191 | if (overloadIndex === selectorOverloadIndex) {
|
192 | matches.push(astDeclaration);
|
193 | }
|
194 | }
|
195 | if (matches.length === 0) {
|
196 | return new ResolverFailure(`An overload for "${astSymbolName}" was not found that matches the` +
|
197 | ` TSDoc selector ":${selectorOverloadIndex}"`);
|
198 | }
|
199 | if (matches.length > 1) {
|
200 |
|
201 |
|
202 | const nonAncillaryMatch = this._tryDisambiguateAncillaryMatches(matches);
|
203 | if (nonAncillaryMatch) {
|
204 | return nonAncillaryMatch;
|
205 | }
|
206 | return new ResolverFailure(`More than one declaration for "${astSymbolName}" matches the` +
|
207 | ` TSDoc selector ":${selectorOverloadIndex}"`);
|
208 | }
|
209 | return matches[0];
|
210 | }
|
211 | |
212 |
|
213 |
|
214 |
|
215 | _tryDisambiguateAncillaryMatches(matches) {
|
216 | let result = undefined;
|
217 | for (const match of matches) {
|
218 | const declarationMetadata = this._collector.fetchDeclarationMetadata(match);
|
219 | if (!declarationMetadata.isAncillary) {
|
220 | if (result) {
|
221 | return undefined;
|
222 | }
|
223 | result = match;
|
224 | }
|
225 | }
|
226 | return result;
|
227 | }
|
228 | }
|
229 | exports.AstReferenceResolver = AstReferenceResolver;
|
230 |
|
\ | No newline at end of file |