UNPKG

47.2 kBJavaScriptView Raw
1/* eslint-disable max-lines */
2/* eslint-disable @typescript-eslint/array-type */
3/* eslint-disable no-return-assign */
4/* eslint-disable no-sequences */
5/* eslint-disable no-inner-declarations */
6/* eslint-disable @typescript-eslint/no-use-before-define */
7/* eslint-disable @typescript-eslint/naming-convention */
8var __extends = (this && this.__extends) || (function () {
9 var extendStatics = function (d, b) {
10 extendStatics = Object.setPrototypeOf ||
11 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
12 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
13 return extendStatics(d, b);
14 };
15 return function (d, b) {
16 extendStatics(d, b);
17 function __() { this.constructor = d; }
18 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
19 };
20})();
21// NOTE: See DeclarationReference.grammarkdown for information on the underlying grammar.
22import { StringChecks } from '../parser/StringChecks';
23/**
24 * Represents a reference to a declaration.
25 * @beta
26 */
27var DeclarationReference = /** @class */ (function () {
28 function DeclarationReference(source, navigation, symbol) {
29 this._source = source;
30 this._navigation = navigation;
31 this._symbol = symbol;
32 }
33 Object.defineProperty(DeclarationReference.prototype, "source", {
34 get: function () {
35 return this._source;
36 },
37 enumerable: false,
38 configurable: true
39 });
40 Object.defineProperty(DeclarationReference.prototype, "navigation", {
41 get: function () {
42 if (!this._source || !this._symbol) {
43 return undefined;
44 }
45 if (this._source === GlobalSource.instance) {
46 return "~" /* Locals */;
47 }
48 if (this._navigation === undefined) {
49 return "." /* Exports */;
50 }
51 return this._navigation;
52 },
53 enumerable: false,
54 configurable: true
55 });
56 Object.defineProperty(DeclarationReference.prototype, "symbol", {
57 get: function () {
58 return this._symbol;
59 },
60 enumerable: false,
61 configurable: true
62 });
63 Object.defineProperty(DeclarationReference.prototype, "isEmpty", {
64 get: function () {
65 return this.source === undefined && this.symbol === undefined;
66 },
67 enumerable: false,
68 configurable: true
69 });
70 DeclarationReference.parse = function (text) {
71 var parser = new Parser(text);
72 var reference = parser.parseDeclarationReference();
73 if (parser.errors.length) {
74 throw new SyntaxError("Invalid DeclarationReference '" + text + "':\n " + parser.errors.join('\n '));
75 }
76 if (!parser.eof) {
77 throw new SyntaxError("Invalid DeclarationReference '" + text + "'");
78 }
79 return reference;
80 };
81 DeclarationReference.parseComponent = function (text) {
82 if (text[0] === '[') {
83 return ComponentReference.parse(text);
84 }
85 else {
86 return new ComponentString(text, true);
87 }
88 };
89 /**
90 * Determines whether the provided string is a well-formed symbol navigation component string.
91 */
92 DeclarationReference.isWellFormedComponentString = function (text) {
93 var scanner = new Scanner(text);
94 return scanner.scan() === 16 /* String */
95 ? scanner.scan() === 1 /* EofToken */
96 : scanner.token() === 17 /* Text */
97 ? scanner.scan() === 1 /* EofToken */
98 : scanner.token() === 1 /* EofToken */;
99 };
100 /**
101 * Escapes a string for use as a symbol navigation component. If the string contains any of `!.#~:,"{}()@` or starts
102 * with `[`, it is enclosed in quotes.
103 */
104 DeclarationReference.escapeComponentString = function (text) {
105 if (text.length === 0) {
106 return '""';
107 }
108 var ch = text.charAt(0);
109 if (ch === '[' || ch === '"' || !this.isWellFormedComponentString(text)) {
110 return JSON.stringify(text);
111 }
112 return text;
113 };
114 /**
115 * Unescapes a string used as a symbol navigation component.
116 */
117 DeclarationReference.unescapeComponentString = function (text) {
118 if (text.length >= 2 && text.charAt(0) === '"' && text.charAt(text.length - 1) === '"') {
119 try {
120 return JSON.parse(text);
121 }
122 catch (_a) {
123 throw new SyntaxError("Invalid Component '" + text + "'");
124 }
125 }
126 if (!this.isWellFormedComponentString(text)) {
127 throw new SyntaxError("Invalid Component '" + text + "'");
128 }
129 return text;
130 };
131 /**
132 * Determines whether the provided string is a well-formed module source string. The string may not
133 * have a trailing `!` character.
134 */
135 DeclarationReference.isWellFormedModuleSourceString = function (text) {
136 var scanner = new Scanner(text + '!');
137 return (scanner.rescanModuleSource() === 18 /* ModuleSource */ &&
138 !scanner.stringIsUnterminated &&
139 scanner.scan() === 8 /* ExclamationToken */ &&
140 scanner.scan() === 1 /* EofToken */);
141 };
142 /**
143 * Escapes a string for use as a module source. If the string contains any of `!"` it is enclosed in quotes.
144 */
145 DeclarationReference.escapeModuleSourceString = function (text) {
146 if (text.length === 0) {
147 return '""';
148 }
149 var ch = text.charAt(0);
150 if (ch === '"' || !this.isWellFormedModuleSourceString(text)) {
151 return JSON.stringify(text);
152 }
153 return text;
154 };
155 /**
156 * Unescapes a string used as a module source. The string may not have a trailing `!` character.
157 */
158 DeclarationReference.unescapeModuleSourceString = function (text) {
159 if (text.length >= 2 && text.charAt(0) === '"' && text.charAt(text.length - 1) === '"') {
160 try {
161 return JSON.parse(text);
162 }
163 catch (_a) {
164 throw new SyntaxError("Invalid Module source '" + text + "'");
165 }
166 }
167 if (!this.isWellFormedModuleSourceString(text)) {
168 throw new SyntaxError("Invalid Module source '" + text + "'");
169 }
170 return text;
171 };
172 DeclarationReference.empty = function () {
173 return new DeclarationReference();
174 };
175 DeclarationReference.package = function (packageName, importPath) {
176 return new DeclarationReference(ModuleSource.fromPackage(packageName, importPath));
177 };
178 DeclarationReference.module = function (path, userEscaped) {
179 return new DeclarationReference(new ModuleSource(path, userEscaped));
180 };
181 DeclarationReference.global = function () {
182 return new DeclarationReference(GlobalSource.instance);
183 };
184 DeclarationReference.from = function (base) {
185 return base || this.empty();
186 };
187 DeclarationReference.prototype.withSource = function (source) {
188 return this._source === source ? this : new DeclarationReference(source, this._navigation, this._symbol);
189 };
190 DeclarationReference.prototype.withNavigation = function (navigation) {
191 return this._navigation === navigation
192 ? this
193 : new DeclarationReference(this._source, navigation, this._symbol);
194 };
195 DeclarationReference.prototype.withSymbol = function (symbol) {
196 return this._symbol === symbol ? this : new DeclarationReference(this._source, this._navigation, symbol);
197 };
198 DeclarationReference.prototype.withComponentPath = function (componentPath) {
199 return this.withSymbol(this.symbol ? this.symbol.withComponentPath(componentPath) : new SymbolReference(componentPath));
200 };
201 DeclarationReference.prototype.withMeaning = function (meaning) {
202 if (!this.symbol) {
203 if (meaning === undefined) {
204 return this;
205 }
206 return this.withSymbol(SymbolReference.empty().withMeaning(meaning));
207 }
208 return this.withSymbol(this.symbol.withMeaning(meaning));
209 };
210 DeclarationReference.prototype.withOverloadIndex = function (overloadIndex) {
211 if (!this.symbol) {
212 if (overloadIndex === undefined) {
213 return this;
214 }
215 return this.withSymbol(SymbolReference.empty().withOverloadIndex(overloadIndex));
216 }
217 return this.withSymbol(this.symbol.withOverloadIndex(overloadIndex));
218 };
219 DeclarationReference.prototype.addNavigationStep = function (navigation, component) {
220 if (this.symbol) {
221 return this.withSymbol(this.symbol.addNavigationStep(navigation, component));
222 }
223 if (navigation === "#" /* Members */) {
224 navigation = "." /* Exports */;
225 }
226 var symbol = new SymbolReference(new ComponentRoot(Component.from(component)));
227 return new DeclarationReference(this.source, navigation, symbol);
228 };
229 DeclarationReference.prototype.toString = function () {
230 var navigation = this._source instanceof ModuleSource && this._symbol && this.navigation === "~" /* Locals */
231 ? '~'
232 : '';
233 return "" + (this.source || '') + navigation + (this.symbol || '');
234 };
235 return DeclarationReference;
236}());
237export { DeclarationReference };
238/**
239 * Represents a module.
240 * @beta
241 */
242var ModuleSource = /** @class */ (function () {
243 function ModuleSource(path, userEscaped) {
244 if (userEscaped === void 0) { userEscaped = true; }
245 this.escapedPath =
246 this instanceof ParsedModuleSource ? path : escapeModuleSourceIfNeeded(path, userEscaped);
247 }
248 Object.defineProperty(ModuleSource.prototype, "path", {
249 get: function () {
250 return this._path || (this._path = DeclarationReference.unescapeModuleSourceString(this.escapedPath));
251 },
252 enumerable: false,
253 configurable: true
254 });
255 Object.defineProperty(ModuleSource.prototype, "packageName", {
256 get: function () {
257 return this._getOrParsePathComponents().packageName;
258 },
259 enumerable: false,
260 configurable: true
261 });
262 Object.defineProperty(ModuleSource.prototype, "scopeName", {
263 get: function () {
264 var scopeName = this._getOrParsePathComponents().scopeName;
265 return scopeName ? '@' + scopeName : '';
266 },
267 enumerable: false,
268 configurable: true
269 });
270 Object.defineProperty(ModuleSource.prototype, "unscopedPackageName", {
271 get: function () {
272 return this._getOrParsePathComponents().unscopedPackageName;
273 },
274 enumerable: false,
275 configurable: true
276 });
277 Object.defineProperty(ModuleSource.prototype, "importPath", {
278 get: function () {
279 return this._getOrParsePathComponents().importPath || '';
280 },
281 enumerable: false,
282 configurable: true
283 });
284 ModuleSource.fromScopedPackage = function (scopeName, unscopedPackageName, importPath) {
285 var packageName = unscopedPackageName;
286 if (scopeName) {
287 if (scopeName.charAt(0) === '@') {
288 scopeName = scopeName.slice(1);
289 }
290 packageName = "@" + scopeName + "/" + unscopedPackageName;
291 }
292 var parsed = { packageName: packageName, scopeName: scopeName || '', unscopedPackageName: unscopedPackageName };
293 return this._fromPackageName(parsed, packageName, importPath);
294 };
295 ModuleSource.fromPackage = function (packageName, importPath) {
296 return this._fromPackageName(parsePackageName(packageName), packageName, importPath);
297 };
298 ModuleSource._fromPackageName = function (parsed, packageName, importPath) {
299 if (!parsed) {
300 throw new Error('Parsed package must be provided.');
301 }
302 var packageNameError = StringChecks.explainIfInvalidPackageName(packageName);
303 if (packageNameError) {
304 throw new SyntaxError("Invalid NPM package name: " + packageNameError);
305 }
306 var path = packageName;
307 if (importPath) {
308 if (invalidImportPathRegExp.test(importPath)) {
309 throw new SyntaxError("Invalid import path '" + importPath);
310 }
311 path += '/' + importPath;
312 parsed.importPath = importPath;
313 }
314 var source = new ModuleSource(path);
315 source._pathComponents = parsed;
316 return source;
317 };
318 ModuleSource.prototype.toString = function () {
319 return this.escapedPath + "!";
320 };
321 ModuleSource.prototype._getOrParsePathComponents = function () {
322 if (!this._pathComponents) {
323 var path = this.path;
324 var parsed = parsePackageName(path);
325 if (parsed && !StringChecks.explainIfInvalidPackageName(parsed.packageName)) {
326 this._pathComponents = parsed;
327 }
328 else {
329 this._pathComponents = {
330 packageName: '',
331 scopeName: '',
332 unscopedPackageName: '',
333 importPath: path
334 };
335 }
336 }
337 return this._pathComponents;
338 };
339 return ModuleSource;
340}());
341export { ModuleSource };
342var ParsedModuleSource = /** @class */ (function (_super) {
343 __extends(ParsedModuleSource, _super);
344 function ParsedModuleSource() {
345 return _super !== null && _super.apply(this, arguments) || this;
346 }
347 return ParsedModuleSource;
348}(ModuleSource));
349// matches the following:
350// 'foo' -> ["foo", "foo", undefined, "foo", undefined]
351// 'foo/bar' -> ["foo/bar", "foo", undefined, "foo", "bar"]
352// '@scope/foo' -> ["@scope/foo", "@scope/foo", "scope", "foo", undefined]
353// '@scope/foo/bar' -> ["@scope/foo/bar", "@scope/foo", "scope", "foo", "bar"]
354// does not match:
355// '/'
356// '@/'
357// '@scope/'
358// capture groups:
359// 1. The package name (including scope)
360// 2. The scope name (excluding the leading '@')
361// 3. The unscoped package name
362// 4. The package-relative import path
363var packageNameRegExp = /^((?:@([^/]+?)\/)?([^/]+?))(?:\/(.+))?$/;
364// no leading './' or '.\'
365// no leading '../' or '..\'
366// no leading '/' or '\'
367// not '.' or '..'
368var invalidImportPathRegExp = /^(\.\.?([\\/]|$)|[\\/])/;
369// eslint-disable-next-line @rushstack/no-new-null
370function parsePackageName(text) {
371 var match = packageNameRegExp.exec(text);
372 if (!match) {
373 return match;
374 }
375 var _a = match[1], packageName = _a === void 0 ? '' : _a, _b = match[2], scopeName = _b === void 0 ? '' : _b, _c = match[3], unscopedPackageName = _c === void 0 ? '' : _c, importPath = match[4];
376 return { packageName: packageName, scopeName: scopeName, unscopedPackageName: unscopedPackageName, importPath: importPath };
377}
378/**
379 * Represents the global scope.
380 * @beta
381 */
382var GlobalSource = /** @class */ (function () {
383 function GlobalSource() {
384 }
385 GlobalSource.prototype.toString = function () {
386 return '!';
387 };
388 GlobalSource.instance = new GlobalSource();
389 return GlobalSource;
390}());
391export { GlobalSource };
392/**
393 * @beta
394 */
395// eslint-disable-next-line @typescript-eslint/no-namespace
396export var Component;
397(function (Component) {
398 function from(value) {
399 if (typeof value === 'string') {
400 return new ComponentString(value);
401 }
402 if (value instanceof DeclarationReference) {
403 return new ComponentReference(value);
404 }
405 return value;
406 }
407 Component.from = from;
408})(Component || (Component = {}));
409/**
410 * @beta
411 */
412var ComponentString = /** @class */ (function () {
413 function ComponentString(text, userEscaped) {
414 this.text = this instanceof ParsedComponentString ? text : escapeComponentIfNeeded(text, userEscaped);
415 }
416 ComponentString.prototype.toString = function () {
417 return this.text;
418 };
419 return ComponentString;
420}());
421export { ComponentString };
422var ParsedComponentString = /** @class */ (function (_super) {
423 __extends(ParsedComponentString, _super);
424 function ParsedComponentString() {
425 return _super !== null && _super.apply(this, arguments) || this;
426 }
427 return ParsedComponentString;
428}(ComponentString));
429/**
430 * @beta
431 */
432var ComponentReference = /** @class */ (function () {
433 function ComponentReference(reference) {
434 this.reference = reference;
435 }
436 ComponentReference.parse = function (text) {
437 if (text.length > 2 && text.charAt(0) === '[' && text.charAt(text.length - 1) === ']') {
438 return new ComponentReference(DeclarationReference.parse(text.slice(1, -1)));
439 }
440 throw new SyntaxError("Invalid component reference: '" + text + "'");
441 };
442 ComponentReference.prototype.withReference = function (reference) {
443 return this.reference === reference ? this : new ComponentReference(reference);
444 };
445 ComponentReference.prototype.toString = function () {
446 return "[" + this.reference + "]";
447 };
448 return ComponentReference;
449}());
450export { ComponentReference };
451/**
452 * @beta
453 */
454var ComponentPathBase = /** @class */ (function () {
455 function ComponentPathBase(component) {
456 this.component = component;
457 }
458 ComponentPathBase.prototype.addNavigationStep = function (navigation, component) {
459 // tslint:disable-next-line:no-use-before-declare
460 return new ComponentNavigation(this, navigation, Component.from(component));
461 };
462 return ComponentPathBase;
463}());
464export { ComponentPathBase };
465/**
466 * @beta
467 */
468var ComponentRoot = /** @class */ (function (_super) {
469 __extends(ComponentRoot, _super);
470 function ComponentRoot() {
471 return _super !== null && _super.apply(this, arguments) || this;
472 }
473 ComponentRoot.prototype.withComponent = function (component) {
474 return this.component === component ? this : new ComponentRoot(Component.from(component));
475 };
476 ComponentRoot.prototype.toString = function () {
477 return this.component.toString();
478 };
479 return ComponentRoot;
480}(ComponentPathBase));
481export { ComponentRoot };
482/**
483 * @beta
484 */
485var ComponentNavigation = /** @class */ (function (_super) {
486 __extends(ComponentNavigation, _super);
487 function ComponentNavigation(parent, navigation, component) {
488 var _this = _super.call(this, component) || this;
489 _this.parent = parent;
490 _this.navigation = navigation;
491 return _this;
492 }
493 ComponentNavigation.prototype.withParent = function (parent) {
494 return this.parent === parent ? this : new ComponentNavigation(parent, this.navigation, this.component);
495 };
496 ComponentNavigation.prototype.withNavigation = function (navigation) {
497 return this.navigation === navigation
498 ? this
499 : new ComponentNavigation(this.parent, navigation, this.component);
500 };
501 ComponentNavigation.prototype.withComponent = function (component) {
502 return this.component === component
503 ? this
504 : new ComponentNavigation(this.parent, this.navigation, Component.from(component));
505 };
506 ComponentNavigation.prototype.toString = function () {
507 return "" + this.parent + formatNavigation(this.navigation) + this.component;
508 };
509 return ComponentNavigation;
510}(ComponentPathBase));
511export { ComponentNavigation };
512/**
513 * Represents a reference to a TypeScript symbol.
514 * @beta
515 */
516var SymbolReference = /** @class */ (function () {
517 function SymbolReference(component, _a) {
518 var _b = _a === void 0 ? {} : _a, meaning = _b.meaning, overloadIndex = _b.overloadIndex;
519 this.componentPath = component;
520 this.overloadIndex = overloadIndex;
521 this.meaning = meaning;
522 }
523 SymbolReference.empty = function () {
524 return new SymbolReference(/*component*/ undefined);
525 };
526 SymbolReference.prototype.withComponentPath = function (componentPath) {
527 return this.componentPath === componentPath
528 ? this
529 : new SymbolReference(componentPath, {
530 meaning: this.meaning,
531 overloadIndex: this.overloadIndex
532 });
533 };
534 SymbolReference.prototype.withMeaning = function (meaning) {
535 return this.meaning === meaning
536 ? this
537 : new SymbolReference(this.componentPath, {
538 meaning: meaning,
539 overloadIndex: this.overloadIndex
540 });
541 };
542 SymbolReference.prototype.withOverloadIndex = function (overloadIndex) {
543 return this.overloadIndex === overloadIndex
544 ? this
545 : new SymbolReference(this.componentPath, {
546 meaning: this.meaning,
547 overloadIndex: overloadIndex
548 });
549 };
550 SymbolReference.prototype.addNavigationStep = function (navigation, component) {
551 if (!this.componentPath) {
552 throw new Error('Cannot add a navigation step to an empty symbol reference.');
553 }
554 return new SymbolReference(this.componentPath.addNavigationStep(navigation, component));
555 };
556 SymbolReference.prototype.toString = function () {
557 var result = "" + (this.componentPath || '');
558 if (this.meaning && this.overloadIndex !== undefined) {
559 result += ":" + this.meaning + "(" + this.overloadIndex + ")";
560 }
561 else if (this.meaning) {
562 result += ":" + this.meaning;
563 }
564 else if (this.overloadIndex !== undefined) {
565 result += ":" + this.overloadIndex;
566 }
567 return result;
568 };
569 return SymbolReference;
570}());
571export { SymbolReference };
572function tokenToString(token) {
573 switch (token) {
574 case 2 /* OpenBraceToken */:
575 return '{';
576 case 3 /* CloseBraceToken */:
577 return '}';
578 case 4 /* OpenParenToken */:
579 return '(';
580 case 5 /* CloseParenToken */:
581 return ')';
582 case 6 /* OpenBracketToken */:
583 return '[';
584 case 7 /* CloseBracketToken */:
585 return ']';
586 case 8 /* ExclamationToken */:
587 return '!';
588 case 9 /* DotToken */:
589 return '.';
590 case 10 /* HashToken */:
591 return '#';
592 case 11 /* TildeToken */:
593 return '~';
594 case 12 /* ColonToken */:
595 return ':';
596 case 13 /* CommaToken */:
597 return ',';
598 case 14 /* AtToken */:
599 return '@';
600 case 19 /* ClassKeyword */:
601 return 'class';
602 case 20 /* InterfaceKeyword */:
603 return 'interface';
604 case 21 /* TypeKeyword */:
605 return 'type';
606 case 22 /* EnumKeyword */:
607 return 'enum';
608 case 23 /* NamespaceKeyword */:
609 return 'namespace';
610 case 24 /* FunctionKeyword */:
611 return 'function';
612 case 25 /* VarKeyword */:
613 return 'var';
614 case 26 /* ConstructorKeyword */:
615 return 'constructor';
616 case 27 /* MemberKeyword */:
617 return 'member';
618 case 28 /* EventKeyword */:
619 return 'event';
620 case 29 /* CallKeyword */:
621 return 'call';
622 case 30 /* NewKeyword */:
623 return 'new';
624 case 31 /* IndexKeyword */:
625 return 'index';
626 case 32 /* ComplexKeyword */:
627 return 'complex';
628 case 0 /* None */:
629 return '<none>';
630 case 1 /* EofToken */:
631 return '<eof>';
632 case 15 /* DecimalDigits */:
633 return '<decimal digits>';
634 case 16 /* String */:
635 return '<string>';
636 case 17 /* Text */:
637 return '<text>';
638 case 18 /* ModuleSource */:
639 return '<module source>';
640 }
641}
642var Scanner = /** @class */ (function () {
643 function Scanner(text) {
644 this._pos = 0;
645 this._tokenPos = 0;
646 this._stringIsUnterminated = false;
647 this._token = 0 /* None */;
648 this._text = text;
649 }
650 Object.defineProperty(Scanner.prototype, "stringIsUnterminated", {
651 get: function () {
652 return this._stringIsUnterminated;
653 },
654 enumerable: false,
655 configurable: true
656 });
657 Object.defineProperty(Scanner.prototype, "text", {
658 get: function () {
659 return this._text;
660 },
661 enumerable: false,
662 configurable: true
663 });
664 Object.defineProperty(Scanner.prototype, "tokenText", {
665 get: function () {
666 return this._text.slice(this._tokenPos, this._pos);
667 },
668 enumerable: false,
669 configurable: true
670 });
671 Object.defineProperty(Scanner.prototype, "eof", {
672 get: function () {
673 return this._pos >= this._text.length;
674 },
675 enumerable: false,
676 configurable: true
677 });
678 Scanner.prototype.token = function () {
679 return this._token;
680 };
681 Scanner.prototype.speculate = function (cb) {
682 var tokenPos = this._tokenPos;
683 var pos = this._pos;
684 var text = this._text;
685 var token = this._token;
686 var stringIsUnterminated = this._stringIsUnterminated;
687 var accepted = false;
688 try {
689 var accept = function () {
690 accepted = true;
691 };
692 return cb(accept);
693 }
694 finally {
695 if (!accepted) {
696 this._tokenPos = tokenPos;
697 this._pos = pos;
698 this._text = text;
699 this._token = token;
700 this._stringIsUnterminated = stringIsUnterminated;
701 }
702 }
703 };
704 Scanner.prototype.scan = function () {
705 if (!this.eof) {
706 this._tokenPos = this._pos;
707 this._stringIsUnterminated = false;
708 while (!this.eof) {
709 var ch = this._text.charAt(this._pos++);
710 switch (ch) {
711 case '{':
712 return (this._token = 2 /* OpenBraceToken */);
713 case '}':
714 return (this._token = 3 /* CloseBraceToken */);
715 case '(':
716 return (this._token = 4 /* OpenParenToken */);
717 case ')':
718 return (this._token = 5 /* CloseParenToken */);
719 case '[':
720 return (this._token = 6 /* OpenBracketToken */);
721 case ']':
722 return (this._token = 7 /* CloseBracketToken */);
723 case '!':
724 return (this._token = 8 /* ExclamationToken */);
725 case '.':
726 return (this._token = 9 /* DotToken */);
727 case '#':
728 return (this._token = 10 /* HashToken */);
729 case '~':
730 return (this._token = 11 /* TildeToken */);
731 case ':':
732 return (this._token = 12 /* ColonToken */);
733 case ',':
734 return (this._token = 13 /* CommaToken */);
735 case '@':
736 return (this._token = 14 /* AtToken */);
737 case '"':
738 this.scanString();
739 return (this._token = 16 /* String */);
740 default:
741 this.scanText();
742 return (this._token = 17 /* Text */);
743 }
744 }
745 }
746 return (this._token = 1 /* EofToken */);
747 };
748 Scanner.prototype.rescanModuleSource = function () {
749 var _this = this;
750 switch (this._token) {
751 case 18 /* ModuleSource */:
752 case 8 /* ExclamationToken */:
753 case 1 /* EofToken */:
754 return this._token;
755 }
756 return this.speculate(function (accept) {
757 if (!_this.eof) {
758 _this._pos = _this._tokenPos;
759 _this._stringIsUnterminated = false;
760 var scanned = 'none';
761 while (!_this.eof) {
762 var ch = _this._text[_this._pos];
763 if (ch === '!') {
764 if (scanned === 'none') {
765 return _this._token;
766 }
767 accept();
768 return (_this._token = 18 /* ModuleSource */);
769 }
770 _this._pos++;
771 if (ch === '"') {
772 if (scanned === 'other') {
773 // strings not allowed after scanning any other characters
774 return _this._token;
775 }
776 scanned = 'string';
777 _this.scanString();
778 }
779 else {
780 if (scanned === 'string') {
781 // no other tokens allowed after string
782 return _this._token;
783 }
784 scanned = 'other';
785 if (!isPunctuator(ch)) {
786 _this.scanText();
787 }
788 }
789 }
790 }
791 return _this._token;
792 });
793 };
794 Scanner.prototype.rescanMeaning = function () {
795 if (this._token === 17 /* Text */) {
796 var tokenText = this.tokenText;
797 switch (tokenText) {
798 case 'class':
799 return (this._token = 19 /* ClassKeyword */);
800 case 'interface':
801 return (this._token = 20 /* InterfaceKeyword */);
802 case 'type':
803 return (this._token = 21 /* TypeKeyword */);
804 case 'enum':
805 return (this._token = 22 /* EnumKeyword */);
806 case 'namespace':
807 return (this._token = 23 /* NamespaceKeyword */);
808 case 'function':
809 return (this._token = 24 /* FunctionKeyword */);
810 case 'var':
811 return (this._token = 25 /* VarKeyword */);
812 case 'constructor':
813 return (this._token = 26 /* ConstructorKeyword */);
814 case 'member':
815 return (this._token = 27 /* MemberKeyword */);
816 case 'event':
817 return (this._token = 28 /* EventKeyword */);
818 case 'call':
819 return (this._token = 29 /* CallKeyword */);
820 case 'new':
821 return (this._token = 30 /* NewKeyword */);
822 case 'index':
823 return (this._token = 31 /* IndexKeyword */);
824 case 'complex':
825 return (this._token = 32 /* ComplexKeyword */);
826 }
827 }
828 return this._token;
829 };
830 Scanner.prototype.rescanDecimalDigits = function () {
831 if (this._token === 17 /* Text */) {
832 var tokenText = this.tokenText;
833 if (/^\d+$/.test(tokenText)) {
834 return (this._token = 15 /* DecimalDigits */);
835 }
836 }
837 return this._token;
838 };
839 Scanner.prototype.scanString = function () {
840 while (!this.eof) {
841 var ch = this._text.charAt(this._pos++);
842 switch (ch) {
843 case '"':
844 return;
845 case '\\':
846 this.scanEscapeSequence();
847 break;
848 default:
849 if (isLineTerminator(ch)) {
850 this._stringIsUnterminated = true;
851 return;
852 }
853 }
854 }
855 this._stringIsUnterminated = true;
856 };
857 Scanner.prototype.scanEscapeSequence = function () {
858 if (this.eof) {
859 this._stringIsUnterminated = true;
860 return;
861 }
862 var ch = this._text.charAt(this._pos);
863 // EscapeSequence:: CharacterEscapeSequence
864 if (isCharacterEscapeSequence(ch)) {
865 this._pos++;
866 return;
867 }
868 // EscapeSequence:: `0` [lookahead != DecimalDigit]
869 if (ch === '0' &&
870 (this._pos + 1 === this._text.length || !isDecimalDigit(this._text.charAt(this._pos + 1)))) {
871 this._pos++;
872 return;
873 }
874 // EscapeSequence:: HexEscapeSequence
875 if (ch === 'x' &&
876 this._pos + 3 <= this._text.length &&
877 isHexDigit(this._text.charAt(this._pos + 1)) &&
878 isHexDigit(this._text.charAt(this._pos + 2))) {
879 this._pos += 3;
880 return;
881 }
882 // EscapeSequence:: UnicodeEscapeSequence
883 // UnicodeEscapeSequence:: `u` Hex4Digits
884 if (ch === 'u' &&
885 this._pos + 5 <= this._text.length &&
886 isHexDigit(this._text.charAt(this._pos + 1)) &&
887 isHexDigit(this._text.charAt(this._pos + 2)) &&
888 isHexDigit(this._text.charAt(this._pos + 3)) &&
889 isHexDigit(this._text.charAt(this._pos + 4))) {
890 this._pos += 5;
891 return;
892 }
893 // EscapeSequence:: UnicodeEscapeSequence
894 // UnicodeEscapeSequence:: `u` `{` CodePoint `}`
895 if (ch === 'u' && this._pos + 4 <= this._text.length && this._text.charAt(this._pos + 1) === '{') {
896 var hexDigits = this._text.charAt(this._pos + 2);
897 if (isHexDigit(hexDigits)) {
898 for (var i = this._pos + 3; i < this._text.length; i++) {
899 var ch2 = this._text.charAt(i);
900 if (ch2 === '}') {
901 var mv = parseInt(hexDigits, 16);
902 if (mv <= 0x10ffff) {
903 this._pos = i + 1;
904 return;
905 }
906 break;
907 }
908 if (!isHexDigit(ch2)) {
909 hexDigits += ch2;
910 break;
911 }
912 }
913 }
914 }
915 this._stringIsUnterminated = true;
916 };
917 Scanner.prototype.scanText = function () {
918 while (this._pos < this._text.length) {
919 var ch = this._text.charAt(this._pos);
920 if (isPunctuator(ch) || ch === '"') {
921 return;
922 }
923 this._pos++;
924 }
925 };
926 return Scanner;
927}());
928var Parser = /** @class */ (function () {
929 function Parser(text) {
930 this._errors = [];
931 this._scanner = new Scanner(text);
932 this._scanner.scan();
933 }
934 Object.defineProperty(Parser.prototype, "eof", {
935 get: function () {
936 return this.token() === 1 /* EofToken */;
937 },
938 enumerable: false,
939 configurable: true
940 });
941 Object.defineProperty(Parser.prototype, "errors", {
942 get: function () {
943 return this._errors;
944 },
945 enumerable: false,
946 configurable: true
947 });
948 Parser.prototype.parseDeclarationReference = function () {
949 var source;
950 var navigation;
951 var symbol;
952 if (this.optionalToken(8 /* ExclamationToken */)) {
953 // Reference to global symbol
954 source = GlobalSource.instance;
955 }
956 else if (this._scanner.rescanModuleSource() === 18 /* ModuleSource */) {
957 source = this.parseModuleSource();
958 // Check for optional `~` navigation token.
959 if (this.optionalToken(11 /* TildeToken */)) {
960 navigation = "~" /* Locals */;
961 }
962 }
963 if (this.isStartOfComponent()) {
964 symbol = this.parseSymbol();
965 }
966 else if (this.token() === 12 /* ColonToken */) {
967 symbol = this.parseSymbolRest(new ComponentRoot(new ComponentString('', /*userEscaped*/ true)));
968 }
969 return new DeclarationReference(source, navigation, symbol);
970 };
971 Parser.prototype.parseModuleSourceString = function () {
972 this._scanner.rescanModuleSource();
973 return this.parseTokenString(18 /* ModuleSource */, 'Module source');
974 };
975 Parser.prototype.parseComponentString = function () {
976 switch (this._scanner.token()) {
977 case 16 /* String */:
978 return this.parseString();
979 default:
980 return this.parseComponentCharacters();
981 }
982 };
983 Parser.prototype.token = function () {
984 return this._scanner.token();
985 };
986 Parser.prototype.parseModuleSource = function () {
987 var source = this.parseModuleSourceString();
988 this.expectToken(8 /* ExclamationToken */);
989 return new ParsedModuleSource(source, /*userEscaped*/ true);
990 };
991 Parser.prototype.parseSymbol = function () {
992 var component = this.parseComponentRest(this.parseRootComponent());
993 return this.parseSymbolRest(component);
994 };
995 Parser.prototype.parseSymbolRest = function (component) {
996 var meaning;
997 var overloadIndex;
998 if (this.optionalToken(12 /* ColonToken */)) {
999 meaning = this.tryParseMeaning();
1000 overloadIndex = this.tryParseOverloadIndex(!!meaning);
1001 }
1002 return new SymbolReference(component, { meaning: meaning, overloadIndex: overloadIndex });
1003 };
1004 Parser.prototype.parseRootComponent = function () {
1005 if (!this.isStartOfComponent()) {
1006 return this.fail('Component expected', new ComponentRoot(new ComponentString('', /*userEscaped*/ true)));
1007 }
1008 var component = this.parseComponent();
1009 return new ComponentRoot(component);
1010 };
1011 Parser.prototype.parseComponentRest = function (component) {
1012 for (;;) {
1013 switch (this.token()) {
1014 case 9 /* DotToken */:
1015 case 10 /* HashToken */:
1016 case 11 /* TildeToken */:
1017 var navigation = this.parseNavigation();
1018 var right = this.parseComponent();
1019 component = new ComponentNavigation(component, navigation, right);
1020 break;
1021 default:
1022 return component;
1023 }
1024 }
1025 };
1026 Parser.prototype.parseNavigation = function () {
1027 switch (this._scanner.token()) {
1028 case 9 /* DotToken */:
1029 return this._scanner.scan(), "." /* Exports */;
1030 case 10 /* HashToken */:
1031 return this._scanner.scan(), "#" /* Members */;
1032 case 11 /* TildeToken */:
1033 return this._scanner.scan(), "~" /* Locals */;
1034 default:
1035 return this.fail("Expected '.', '#', or '~'", "." /* Exports */);
1036 }
1037 };
1038 Parser.prototype.tryParseMeaning = function () {
1039 switch (this._scanner.rescanMeaning()) {
1040 case 19 /* ClassKeyword */:
1041 return this._scanner.scan(), "class" /* Class */;
1042 case 20 /* InterfaceKeyword */:
1043 return this._scanner.scan(), "interface" /* Interface */;
1044 case 21 /* TypeKeyword */:
1045 return this._scanner.scan(), "type" /* TypeAlias */;
1046 case 22 /* EnumKeyword */:
1047 return this._scanner.scan(), "enum" /* Enum */;
1048 case 23 /* NamespaceKeyword */:
1049 return this._scanner.scan(), "namespace" /* Namespace */;
1050 case 24 /* FunctionKeyword */:
1051 return this._scanner.scan(), "function" /* Function */;
1052 case 25 /* VarKeyword */:
1053 return this._scanner.scan(), "var" /* Variable */;
1054 case 26 /* ConstructorKeyword */:
1055 return this._scanner.scan(), "constructor" /* Constructor */;
1056 case 27 /* MemberKeyword */:
1057 return this._scanner.scan(), "member" /* Member */;
1058 case 28 /* EventKeyword */:
1059 return this._scanner.scan(), "event" /* Event */;
1060 case 29 /* CallKeyword */:
1061 return this._scanner.scan(), "call" /* CallSignature */;
1062 case 30 /* NewKeyword */:
1063 return this._scanner.scan(), "new" /* ConstructSignature */;
1064 case 31 /* IndexKeyword */:
1065 return this._scanner.scan(), "index" /* IndexSignature */;
1066 case 32 /* ComplexKeyword */:
1067 return this._scanner.scan(), "complex" /* ComplexType */;
1068 default:
1069 return undefined;
1070 }
1071 };
1072 Parser.prototype.tryParseOverloadIndex = function (hasMeaning) {
1073 if (this.optionalToken(4 /* OpenParenToken */)) {
1074 var overloadIndex = this.parseDecimalDigits();
1075 this.expectToken(5 /* CloseParenToken */);
1076 return overloadIndex;
1077 }
1078 else if (!hasMeaning) {
1079 return this.parseDecimalDigits();
1080 }
1081 return undefined;
1082 };
1083 Parser.prototype.parseDecimalDigits = function () {
1084 switch (this._scanner.rescanDecimalDigits()) {
1085 case 15 /* DecimalDigits */:
1086 var value = +this._scanner.tokenText;
1087 this._scanner.scan();
1088 return value;
1089 default:
1090 return this.fail('Decimal digit expected', 0);
1091 }
1092 };
1093 Parser.prototype.isStartOfComponent = function () {
1094 switch (this.token()) {
1095 case 17 /* Text */:
1096 case 16 /* String */:
1097 case 6 /* OpenBracketToken */:
1098 return true;
1099 default:
1100 return false;
1101 }
1102 };
1103 Parser.prototype.parseComponentCharacters = function () {
1104 var text = '';
1105 for (;;) {
1106 switch (this._scanner.token()) {
1107 case 17 /* Text */:
1108 text += this.parseText();
1109 break;
1110 default:
1111 return text;
1112 }
1113 }
1114 };
1115 Parser.prototype.parseTokenString = function (token, tokenString) {
1116 if (this._scanner.token() === token) {
1117 var text = this._scanner.tokenText;
1118 var stringIsUnterminated = this._scanner.stringIsUnterminated;
1119 this._scanner.scan();
1120 if (stringIsUnterminated) {
1121 return this.fail((tokenString || tokenToString(token)) + " is unterminated", text);
1122 }
1123 return text;
1124 }
1125 return this.fail((tokenString || tokenToString(token)) + " expected", '');
1126 };
1127 Parser.prototype.parseText = function () {
1128 return this.parseTokenString(17 /* Text */, 'Text');
1129 };
1130 Parser.prototype.parseString = function () {
1131 return this.parseTokenString(16 /* String */, 'String');
1132 };
1133 Parser.prototype.parseComponent = function () {
1134 switch (this._scanner.token()) {
1135 case 6 /* OpenBracketToken */:
1136 return this.parseBracketedComponent();
1137 default:
1138 return new ParsedComponentString(this.parseComponentString(), /*userEscaped*/ true);
1139 }
1140 };
1141 Parser.prototype.parseBracketedComponent = function () {
1142 this.expectToken(6 /* OpenBracketToken */);
1143 var reference = this.parseDeclarationReference();
1144 this.expectToken(7 /* CloseBracketToken */);
1145 return new ComponentReference(reference);
1146 };
1147 Parser.prototype.optionalToken = function (token) {
1148 if (this._scanner.token() === token) {
1149 this._scanner.scan();
1150 return true;
1151 }
1152 return false;
1153 };
1154 Parser.prototype.expectToken = function (token, message) {
1155 if (this._scanner.token() !== token) {
1156 var expected = tokenToString(token);
1157 var actual = tokenToString(this._scanner.token());
1158 return this.fail(message || "Expected token '" + expected + "', received '" + actual + "' instead.", undefined);
1159 }
1160 this._scanner.scan();
1161 };
1162 Parser.prototype.fail = function (message, fallback) {
1163 this._errors.push(message);
1164 return fallback;
1165 };
1166 return Parser;
1167}());
1168function formatNavigation(navigation) {
1169 switch (navigation) {
1170 case "." /* Exports */:
1171 return '.';
1172 case "#" /* Members */:
1173 return '#';
1174 case "~" /* Locals */:
1175 return '~';
1176 default:
1177 return '';
1178 }
1179}
1180function isCharacterEscapeSequence(ch) {
1181 return isSingleEscapeCharacter(ch) || isNonEscapeCharacter(ch);
1182}
1183function isSingleEscapeCharacter(ch) {
1184 switch (ch) {
1185 case "'":
1186 case '"':
1187 case '\\':
1188 case 'b':
1189 case 'f':
1190 case 'n':
1191 case 'r':
1192 case 't':
1193 case 'v':
1194 return true;
1195 default:
1196 return false;
1197 }
1198}
1199function isNonEscapeCharacter(ch) {
1200 return !isEscapeCharacter(ch) && !isLineTerminator(ch);
1201}
1202function isEscapeCharacter(ch) {
1203 switch (ch) {
1204 case 'x':
1205 case 'u':
1206 return true;
1207 default:
1208 return isSingleEscapeCharacter(ch) || isDecimalDigit(ch);
1209 }
1210}
1211function isLineTerminator(ch) {
1212 switch (ch) {
1213 case '\r':
1214 case '\n':
1215 // TODO: <LS>, <PS>
1216 return true;
1217 default:
1218 return false;
1219 }
1220}
1221function isDecimalDigit(ch) {
1222 switch (ch) {
1223 case '0':
1224 case '1':
1225 case '2':
1226 case '3':
1227 case '4':
1228 case '5':
1229 case '6':
1230 case '7':
1231 case '8':
1232 case '9':
1233 return true;
1234 default:
1235 return false;
1236 }
1237}
1238function isHexDigit(ch) {
1239 switch (ch) {
1240 case 'a':
1241 case 'b':
1242 case 'c':
1243 case 'd':
1244 case 'e':
1245 case 'f':
1246 case 'A':
1247 case 'B':
1248 case 'C':
1249 case 'D':
1250 case 'E':
1251 case 'F':
1252 return true;
1253 default:
1254 return isDecimalDigit(ch);
1255 }
1256}
1257function isPunctuator(ch) {
1258 switch (ch) {
1259 case '{':
1260 case '}':
1261 case '(':
1262 case ')':
1263 case '[':
1264 case ']':
1265 case '!':
1266 case '.':
1267 case '#':
1268 case '~':
1269 case ':':
1270 case ',':
1271 case '@':
1272 return true;
1273 default:
1274 return false;
1275 }
1276}
1277function escapeComponentIfNeeded(text, userEscaped) {
1278 if (userEscaped) {
1279 if (!DeclarationReference.isWellFormedComponentString(text)) {
1280 throw new SyntaxError("Invalid Component '" + text + "'");
1281 }
1282 return text;
1283 }
1284 return DeclarationReference.escapeComponentString(text);
1285}
1286function escapeModuleSourceIfNeeded(text, userEscaped) {
1287 if (userEscaped) {
1288 if (!DeclarationReference.isWellFormedModuleSourceString(text)) {
1289 throw new SyntaxError("Invalid Module source '" + text + "'");
1290 }
1291 return text;
1292 }
1293 return DeclarationReference.escapeModuleSourceString(text);
1294}
1295//# sourceMappingURL=DeclarationReference.js.map
\No newline at end of file