UNPKG

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